jsshuffle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ *.swp
16
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jsshuffle.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 TODO: Write your name
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ jsshuffle
2
+ =========
3
+
4
+ A library to just-in-time randomly obfuscate JS.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/jsshuffle ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'jsshuffle'
4
+ puts JsShuffle::Shuffler.new.shuffle js: ARGF.read
data/jsshuffle.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jsshuffle/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jsshuffle"
8
+ spec.version = Jsshuffle::VERSION
9
+ spec.authors = ["S0lll0s / Sol Bekic"]
10
+ spec.email = ["s0lll0s@blinkenshell.org"]
11
+ spec.summary = %q{A library to just-in-time randomly obfuscate JS}
12
+ spec.homepage = ""
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.6"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+
23
+ spec.add_runtime_dependency "rkelly-remix", "~> 0.0.6"
24
+ end
@@ -0,0 +1,56 @@
1
+ module JsShuffle::Methods
2
+
3
+ # Wraps up a +Method+ to obfuscate / shuffle the JS.
4
+ #
5
+ # When subclassing +Method+ define one or more of the three processing hooks:
6
+ # +preprocess+:: called in the first pass, this hook shouldn't modify the AST
7
+ # +process+:: called as the second pass. Modify the AST here
8
+ # +postprocess+:: called last. This method gets passed the js in string form and is expected to return a string itself
9
+ class Method
10
+ # Returns the hash of default options the +Method+ accepts in the {configure}[rdoc-ref:JsShuffle::Methods::method#configure] method
11
+ def default_config
12
+ return {}
13
+ end
14
+
15
+ # Configures the +Method+ instance given the option hash
16
+ #
17
+ # Parameters:
18
+ # +options+:: The options hash
19
+ def configure( options )
20
+ @options = options
21
+ end
22
+
23
+ # Called in the first pass. Don't modify the AST in here!
24
+ #
25
+ # Parameters:
26
+ # +ast+:: The JS AST
27
+ # +shuffler:: The {Shuffler}[rdoc-ref:JsShuffle::Shuffler] calling the hook
28
+ def preprocess( ast, shuffler )
29
+ end
30
+
31
+ # Called in the second pass. Modify the AST here
32
+ #
33
+ # Parameters:
34
+ # +js+:: The JS AST
35
+ # +shuffler:: The {Shuffler}[rdoc-ref:JsShuffle::Shuffler] calling the hook
36
+ def process( ast, shuffler )
37
+ end
38
+
39
+ # Called last of the three hooks. Return the js!
40
+ #
41
+ # Parameters:
42
+ # +js+:: The JS in string form
43
+ # +shuffler:: The {Shuffler}[rdoc-ref:JsShuffle::Shuffler] calling the hook
44
+ def postprocess( js, shuffler )
45
+ js
46
+ end
47
+
48
+ # Make sure +#respond_to?+ works like expected, even though this class provides the hooks
49
+ def self.inherited( subclass )
50
+ undef_method :preprocess
51
+ undef_method :process
52
+ undef_method :postprocess
53
+ super
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,26 @@
1
+ module JsShuffle::Methods
2
+ # Replaces local variable names with a randomly generated new one
3
+ #
4
+ # pass +:variable_renaming+ in the +:use+ array of a {Parser}[rdoc-ref:JsShuffle::Parser] to use this +Method+.
5
+ class VariableRenaming < Method
6
+ JsShuffle::Methods.methods[:variable_renaming] = self
7
+
8
+ def process( ast, shuffler )
9
+ sourceNodes = ast.select do |node| node.is_a? RKelly::Nodes::SourceElementsNode end
10
+ sourceNodes.each do |node|
11
+ renamed_variables = {}
12
+ node.value.each do |child|
13
+ if child.is_a? RKelly::Nodes::VarStatementNode
14
+ renamed_variables[child.value.first.name] = (child.value.first.name = shuffler.random_new_name )
15
+ elsif child.is_a? RKelly::Nodes::ResolveNode
16
+ child.value = renamed_variables[child.value] if renamed_variables.has_key? child.value
17
+ else
18
+ child.each do |n|
19
+ n.value = renamed_variables[n.value] if n.is_a? RKelly::Nodes::ResolveNode and renamed_variables.has_key? n.value
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module JsShuffle
2
+ module Methods
3
+ class << self
4
+ attr_accessor :methods
5
+ end
6
+ end
7
+ Methods.methods = {}
8
+ end
9
+
10
+ require 'jsshuffle/methods/method.rb'
11
+ require 'jsshuffle/methods/variable_renaming.rb'
@@ -0,0 +1,7 @@
1
+ require 'rails'
2
+
3
+ module JsShuffle
4
+ class Railtie < ::Rails::Railtie
5
+ config.assets.js_compressor = Shuffler.new
6
+ end
7
+ end
@@ -0,0 +1,91 @@
1
+ module JsShuffle
2
+
3
+ # Shuffles a js-program or {RKelly AST}[rdoc-ref:RKelly::Nodes]
4
+ # rdoc-ref:RDoc::Markup
5
+ class Shuffler
6
+ # Instantiate a new {Shuffler}[rdoc-ref:JsShuffle::Shuffler]
7
+ # Parameters:
8
+ # +use+::
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
+ # 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
+ # 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 } )
13
+ @methods = hash[:use]
14
+ @methods = [ @methods ] if @methods.is_a? Symbol
15
+
16
+ @parser = RKelly::Parser.new
17
+
18
+ @methods.collect! do |m|
19
+ next (JsShuffle::Methods.methods[m]).new if m.is_a? Symbol
20
+ next m.new if m.is_a? JsShuffle::Methods::Method
21
+ m
22
+ end
23
+
24
+ @defaults = {}
25
+ @methods.each do |m|
26
+ @defaults.merge! m.default_config if m.is_a? JsShuffle::Methods::Method
27
+ end
28
+ end
29
+
30
+ # Shuffle a javascript program string and return the result
31
+ #
32
+ # Used to make {Shuffler}[rdoc-ref:JsShuffle::Shuffler] available as a +Rails+ JS Preprocessor
33
+ #
34
+ # Parameters:
35
+ # +source+::
36
+ # The js source string
37
+ def compress( source )
38
+ shuffle js: source
39
+ end
40
+
41
+ # Shuffle a js-string or a {RKelly AST}[rdoc-ref:RKelly::Nodes]
42
+ #
43
+ # Parameters:
44
+ # +options+::
45
+ # an option hash containing either
46
+ # +js+:: the javascript source code as a string _or_
47
+ # +ast+:: the parsed javascript source as {RKelly AST}[rdoc-ref:RKelly::Nodes]
48
+ # and optionally the following options:
49
+ # +output+:: the output format, +:string+ or +:ast+
50
+ #
51
+ # all other options are passed on to the {Methods}[rdoc-ref:JsShuffle::Methods] supplied during initialization
52
+ #
53
+ # Returns either a +String+ or {RKelly AST}[rdoc-ref:Rkelly::Nodes], matching the input format or the +output+ value
54
+ def shuffle( hash={} )
55
+ hash = { js: hash } if hash.is_a? String
56
+ options = @defaults.merge(hash)
57
+ @new_names = []
58
+ ast = hash[:ast] || @parser.parse( hash[:js] )
59
+
60
+ @methods.each do |m| m.configure options if m.is_a? JsShuffle::Methods::Method end
61
+
62
+ [:preprocess, :process].each do |pass|
63
+ @methods.each do |m|
64
+ next m.send( pass, ast, self ) if m.is_a? JsShuffle::Methods::Method and m.respond_to? pass
65
+ m.call( pass, ast, self ) if m.respond_to? :call
66
+ end
67
+ end
68
+ js = ast.to_ecma
69
+ @methods.each do |m|
70
+ next (js = m.postprocess( ast, self )) if m.is_a? JsShuffle::Methods::Method and m.respond_to? :postprocess
71
+ js = m.call( :postprocess, js, self ) if m.respond_to? :call
72
+ end
73
+
74
+ if hash.has_key? :output
75
+ return js if hash[:output] == :string
76
+ return @parser.parse( js )
77
+ end
78
+
79
+ return @parser.parse( js ) if hash[:ast]
80
+ js
81
+ end
82
+
83
+ # Generates a random new symbol name
84
+ def random_new_name
85
+ begin
86
+ new_name = ('a'..'z').to_a.shuffle[0,8].join
87
+ end while @new_names.include? new_name
88
+ new_name
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,3 @@
1
+ module Jsshuffle
2
+ VERSION = "0.0.1"
3
+ end
data/lib/jsshuffle.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'rkelly'
5
+
6
+ require 'jsshuffle/version'
7
+ require 'jsshuffle/methods'
8
+ require 'jsshuffle/shuffler'
9
+
10
+ require 'jsshuffle/railtie' if defined?(Rails)
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jsshuffle
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - S0lll0s / Sol Bekic
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-08-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.6'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.6'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '10.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '10.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rkelly-remix
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.0.6
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.6
62
+ description:
63
+ email:
64
+ - s0lll0s@blinkenshell.org
65
+ executables:
66
+ - jsshuffle
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - bin/jsshuffle
76
+ - jsshuffle.gemspec
77
+ - lib/jsshuffle.rb
78
+ - lib/jsshuffle/methods.rb
79
+ - lib/jsshuffle/methods/method.rb
80
+ - lib/jsshuffle/methods/variable_renaming.rb
81
+ - lib/jsshuffle/railtie.rb
82
+ - lib/jsshuffle/shuffler.rb
83
+ - lib/jsshuffle/version.rb
84
+ homepage: ''
85
+ licenses:
86
+ - MIT
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 1.8.23
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: A library to just-in-time randomly obfuscate JS
109
+ test_files: []