jsshuffle 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +56 -2
- data/Rakefile +6 -1
- data/jsshuffle.gemspec +4 -3
- data/lib/jsshuffle/methods.rb +1 -0
- data/lib/jsshuffle/methods/method.rb +3 -3
- data/lib/jsshuffle/methods/parameter_renaming.rb +17 -0
- data/lib/jsshuffle/methods/variable_renaming.rb +2 -4
- data/lib/jsshuffle/shuffler.rb +4 -6
- data/lib/jsshuffle/version.rb +1 -1
- data/test/test_parameter_renaming.rb +45 -0
- data/test/test_shuffler.rb +38 -0
- data/test/test_variable_renaming.rb +34 -0
- metadata +28 -5
data/README.md
CHANGED
@@ -1,4 +1,58 @@
|
|
1
|
-
jsshuffle
|
2
|
-
|
1
|
+
jsshuffle 
|
2
|
+
================================================================
|
3
3
|
|
4
4
|
A library to just-in-time randomly obfuscate JS.
|
5
|
+
|
6
|
+
|
7
|
+
Installation
|
8
|
+
------------
|
9
|
+
|
10
|
+
$ gem install jsshuffle
|
11
|
+
|
12
|
+
and
|
13
|
+
|
14
|
+
require 'jsshuffle'
|
15
|
+
|
16
|
+
should be enough to get you up and running.
|
17
|
+
|
18
|
+
For rails, just add _jsshuffle_ to your Gemfile:
|
19
|
+
|
20
|
+
gem 'jsshuffle', group: :production
|
21
|
+
|
22
|
+
|
23
|
+
Usage
|
24
|
+
-----
|
25
|
+
|
26
|
+
_jsshuffle_ can be used standalone and as a Ruby library.
|
27
|
+
|
28
|
+
The standalone executable takes a filename as a parameter or reads the input from `STDIN` and outputs on `STDOUT`:
|
29
|
+
|
30
|
+
$ jsshuffle <<EOF
|
31
|
+
> var test = 13;
|
32
|
+
> test = (test + 13) * 7;
|
33
|
+
> alert( test );
|
34
|
+
> EOF
|
35
|
+
var dqkwxnvj = 13;
|
36
|
+
dqkwxnvj = (dqkwxnvj + 13) * 7;
|
37
|
+
alert(dqkwxnvj);
|
38
|
+
|
39
|
+
To use _jsshuffle_ in your own Ruby project, instantiate `JsShuffle::Shuffler`:
|
40
|
+
|
41
|
+
require 'jsshuffle'
|
42
|
+
|
43
|
+
shuffler = JsShuffle::Shuffler.new use: :variable_renaming
|
44
|
+
|
45
|
+
puts shuffler.shuffle js: %Q(
|
46
|
+
var variable = "variable";
|
47
|
+
function newFunc( parameter ) {
|
48
|
+
return parameter + " is a cool parameter.";
|
49
|
+
}
|
50
|
+
|
51
|
+
console.log( newFunc( variable ) );
|
52
|
+
)
|
53
|
+
|
54
|
+
Extending JsShuffle
|
55
|
+
-------------------
|
56
|
+
|
57
|
+
You can sublcass `JsShuffle::Methods::Method` and pass the new class as a `use:` argument to `Shuffler#new` or alternatively pass a Block or Proc.
|
58
|
+
For more information view the RDoc.
|
data/Rakefile
CHANGED
data/jsshuffle.gemspec
CHANGED
@@ -17,8 +17,9 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.
|
21
|
-
spec.
|
20
|
+
spec.add_dependency "bundler", "~> 1.6"
|
21
|
+
spec.add_dependency "rake", "~> 10.0"
|
22
|
+
spec.add_dependency "rkelly-remix", "~> 0.0.6"
|
22
23
|
|
23
|
-
spec.
|
24
|
+
spec.add_development_dependency "execjs", "~> 2.2.1"
|
24
25
|
end
|
data/lib/jsshuffle/methods.rb
CHANGED
@@ -47,9 +47,9 @@ module JsShuffle::Methods
|
|
47
47
|
|
48
48
|
# Make sure +#respond_to?+ works like expected, even though this class provides the hooks
|
49
49
|
def self.inherited( subclass )
|
50
|
-
undef_method :preprocess
|
51
|
-
undef_method :process
|
52
|
-
undef_method :postprocess
|
50
|
+
undef_method :preprocess rescue ""
|
51
|
+
undef_method :process rescue ""
|
52
|
+
undef_method :postprocess rescue ""
|
53
53
|
super
|
54
54
|
end
|
55
55
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module JsShuffle::Methods
|
2
|
+
# Replaces local variable names with a randomly generated new one
|
3
|
+
#
|
4
|
+
# pass +:parameter_renaming+ in the +:use+ array of a {Parser}[rdoc-ref:JsShuffle::Parser] to use this +Method+.
|
5
|
+
class ParameterRenaming < Method
|
6
|
+
JsShuffle::Methods.methods[:parameter_renaming] = self
|
7
|
+
|
8
|
+
def process( ast, shuffler )
|
9
|
+
functionNodes = ast.select { |node| node.is_a? RKelly::Nodes::FunctionDeclNode }
|
10
|
+
functionNodes.each do |node|
|
11
|
+
renamed_parameters = {}
|
12
|
+
node.arguments.each { |arg| renamed_parameters[arg.value] = (arg.value = shuffler.random_new_name) }
|
13
|
+
node.function_body.value.each { |child| child.value = renamed_parameters[child.value] if child.is_a? RKelly::Nodes::ResolveNode and renamed_parameters.has_key? child.value }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,7 +6,7 @@ module JsShuffle::Methods
|
|
6
6
|
JsShuffle::Methods.methods[:variable_renaming] = self
|
7
7
|
|
8
8
|
def process( ast, shuffler )
|
9
|
-
sourceNodes = ast.select
|
9
|
+
sourceNodes = ast.select { |node| node.is_a? RKelly::Nodes::SourceElementsNode }
|
10
10
|
sourceNodes.each do |node|
|
11
11
|
renamed_variables = {}
|
12
12
|
node.value.each do |child|
|
@@ -15,9 +15,7 @@ module JsShuffle::Methods
|
|
15
15
|
elsif child.is_a? RKelly::Nodes::ResolveNode
|
16
16
|
child.value = renamed_variables[child.value] if renamed_variables.has_key? child.value
|
17
17
|
else
|
18
|
-
child.each
|
19
|
-
n.value = renamed_variables[n.value] if n.is_a? RKelly::Nodes::ResolveNode and renamed_variables.has_key? n.value
|
20
|
-
end
|
18
|
+
child.each { |n| n.value = renamed_variables[n.value] if n.is_a? RKelly::Nodes::ResolveNode and renamed_variables.has_key? n.value }
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
data/lib/jsshuffle/shuffler.rb
CHANGED
@@ -9,7 +9,7 @@ module JsShuffle
|
|
9
9
|
# A +Symbol+, +Proc+ or a +Class+ inheriting from {JsShuffle::Methods::Method}[rdoc-ref:JsShuffle::Methods::Method] or an +Array+ mixing any of these types.
|
10
10
|
# Symbols are matched to JsShuffle's native {Methods}[rdoc-ref:JsShuffle::Methods] and should be lowercased and underscored (like the filenames of the corresponding +Method+)
|
11
11
|
# Procs are called three times and receive the +pass+ (one of +:preprocess+, +:process+ or +postprocess+), the AST and the {Shuffler}[rdoc-ref:JsShuffle::Shuffler] instance. In the last pass the js string is passed instead of the AST and the Proc is expected to return the modified string
|
12
|
-
def initialize( hash={ use: :variable_renaming } )
|
12
|
+
def initialize( hash={ use: [:variable_renaming, :parameter_renaming] } )
|
13
13
|
@methods = hash[:use]
|
14
14
|
@methods = [ @methods ] if @methods.is_a? Symbol
|
15
15
|
|
@@ -22,9 +22,7 @@ module JsShuffle
|
|
22
22
|
end
|
23
23
|
|
24
24
|
@defaults = {}
|
25
|
-
@methods.each
|
26
|
-
@defaults.merge! m.default_config if m.is_a? JsShuffle::Methods::Method
|
27
|
-
end
|
25
|
+
@methods.each { |m| @defaults.merge! m.default_config if m.is_a? JsShuffle::Methods::Method }
|
28
26
|
end
|
29
27
|
|
30
28
|
# Shuffle a javascript program string and return the result
|
@@ -57,7 +55,7 @@ module JsShuffle
|
|
57
55
|
@new_names = []
|
58
56
|
ast = hash[:ast] || @parser.parse( hash[:js] )
|
59
57
|
|
60
|
-
@methods.each
|
58
|
+
@methods.each { |m| m.configure options if m.is_a? JsShuffle::Methods::Method }
|
61
59
|
|
62
60
|
[:preprocess, :process].each do |pass|
|
63
61
|
@methods.each do |m|
|
@@ -79,7 +77,7 @@ module JsShuffle
|
|
79
77
|
return @parser.parse( js ) if hash[:ast]
|
80
78
|
js
|
81
79
|
end
|
82
|
-
|
80
|
+
|
83
81
|
# Generates a random new symbol name
|
84
82
|
def random_new_name
|
85
83
|
begin
|
data/lib/jsshuffle/version.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'jsshuffle'
|
3
|
+
require 'execjs'
|
4
|
+
|
5
|
+
class ParameterRenamingTest < Test::Unit::TestCase
|
6
|
+
def test_can_include
|
7
|
+
assert_nothing_raised do
|
8
|
+
@shuffler = JsShuffle::Shuffler.new use: :parameter_renaming
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_name_changes
|
13
|
+
assert_nothing_raised { @shuffler = JsShuffle::Shuffler.new use: :parameter_renaming }
|
14
|
+
original = %Q(
|
15
|
+
function double(parameter) {
|
16
|
+
return parameter*2;
|
17
|
+
}
|
18
|
+
)
|
19
|
+
assert_not_equal original,
|
20
|
+
@shuffler.shuffle( js: original )
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_code_works
|
24
|
+
assert_nothing_raised { @shuffler = JsShuffle::Shuffler.new use: :parameter_renaming }
|
25
|
+
shuffled = @shuffler.shuffle js: %Q(
|
26
|
+
function double(parameter) {
|
27
|
+
return parameter*2;
|
28
|
+
}
|
29
|
+
return double(333);
|
30
|
+
)
|
31
|
+
assert_equal 666,
|
32
|
+
ExecJS.exec( shuffled )
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_references_updated
|
36
|
+
assert_nothing_raised { @shuffler = JsShuffle::Shuffler.new use: :parameter_renaming }
|
37
|
+
assert_no_match /parameter/,
|
38
|
+
@shuffler.shuffle( js: %Q(
|
39
|
+
function double(parameter) {
|
40
|
+
return parameter*2;
|
41
|
+
}
|
42
|
+
return double(333);
|
43
|
+
))
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'jsshuffle'
|
3
|
+
require 'execjs'
|
4
|
+
|
5
|
+
class ShufflerTest < Test::Unit::TestCase
|
6
|
+
def test_instantiate
|
7
|
+
assert_nothing_raised do
|
8
|
+
@shuffler = JsShuffle::Shuffler.new
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_default_does_something
|
13
|
+
assert_nothing_raised { @shuffler = JsShuffle::Shuffler.new }
|
14
|
+
original = "var beers_i_had = 5; return beers_i_had;"
|
15
|
+
shuffled = @shuffler.shuffle js: original
|
16
|
+
|
17
|
+
assert_not_equal original, shuffled
|
18
|
+
|
19
|
+
assert_equal 5,
|
20
|
+
ExecJS.exec( shuffled )
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_code_works
|
24
|
+
assert_nothing_raised { @shuffler = JsShuffle::Shuffler.new }
|
25
|
+
shuffled = @shuffler.shuffle js: %Q(
|
26
|
+
var twelve = 12;
|
27
|
+
twelve = twelve + 2;
|
28
|
+
function subtract_three( number ) {
|
29
|
+
var local = number - 3;
|
30
|
+
return local;
|
31
|
+
}
|
32
|
+
return subtract_three( twelve ) + "-ish";
|
33
|
+
)
|
34
|
+
|
35
|
+
assert_equal "11-ish",
|
36
|
+
ExecJS.exec( shuffled )
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'jsshuffle'
|
3
|
+
require 'execjs'
|
4
|
+
|
5
|
+
class VariableRenamingTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@shuffler = JsShuffle::Shuffler.new use: :variable_renaming
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_name_changes
|
11
|
+
original = "var beers_i_had = 5;"
|
12
|
+
assert_not_equal original,
|
13
|
+
@shuffler.shuffle( js: original )
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_references_updated
|
17
|
+
assert_no_match /is_working/,
|
18
|
+
@shuffler.shuffle( js: %Q(
|
19
|
+
var is_working = true;
|
20
|
+
return is_working;
|
21
|
+
))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_code_works
|
25
|
+
shuffled = @shuffler.shuffle js: %Q(
|
26
|
+
var twelve = 12;
|
27
|
+
twelve = twelve + 2;
|
28
|
+
return twelve;
|
29
|
+
)
|
30
|
+
|
31
|
+
assert_equal 14,
|
32
|
+
ExecJS.exec( shuffled )
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsshuffle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-08-
|
12
|
+
date: 2014-08-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: '1.6'
|
22
|
-
type: :
|
22
|
+
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
@@ -35,7 +35,7 @@ dependencies:
|
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: '10.0'
|
38
|
-
type: :
|
38
|
+
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
@@ -59,6 +59,22 @@ dependencies:
|
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 0.0.6
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: execjs
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.2.1
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.2.1
|
62
78
|
description:
|
63
79
|
email:
|
64
80
|
- s0lll0s@blinkenshell.org
|
@@ -77,10 +93,14 @@ files:
|
|
77
93
|
- lib/jsshuffle.rb
|
78
94
|
- lib/jsshuffle/methods.rb
|
79
95
|
- lib/jsshuffle/methods/method.rb
|
96
|
+
- lib/jsshuffle/methods/parameter_renaming.rb
|
80
97
|
- lib/jsshuffle/methods/variable_renaming.rb
|
81
98
|
- lib/jsshuffle/railtie.rb
|
82
99
|
- lib/jsshuffle/shuffler.rb
|
83
100
|
- lib/jsshuffle/version.rb
|
101
|
+
- test/test_parameter_renaming.rb
|
102
|
+
- test/test_shuffler.rb
|
103
|
+
- test/test_variable_renaming.rb
|
84
104
|
homepage: ''
|
85
105
|
licenses:
|
86
106
|
- MIT
|
@@ -106,4 +126,7 @@ rubygems_version: 1.8.23
|
|
106
126
|
signing_key:
|
107
127
|
specification_version: 3
|
108
128
|
summary: A library to just-in-time randomly obfuscate JS
|
109
|
-
test_files:
|
129
|
+
test_files:
|
130
|
+
- test/test_parameter_renaming.rb
|
131
|
+
- test/test_shuffler.rb
|
132
|
+
- test/test_variable_renaming.rb
|