escape_escape_escape 1.1.0 → 1.4.1
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/escape_escape_escape.gemspec +4 -3
- data/lib/escape_escape_escape.rb +73 -11
- data/specs/as_ruby/0003-css_class_name.rb +24 -0
- data/specs/as_ruby/0005-html_id.rb +40 -0
- data/specs/as_ruby/0005-html_tag.rb +43 -0
- data/specs/as_ruby/0021-relative_href.rb +24 -0
- data/specs/as_ruby/0050-json_decode.rb +19 -0
- data/specs/as_ruby/0051-json_encode.rb +19 -0
- data/specs/escape_escape_escape.rb +2 -2
- metadata +36 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 475be5e9a0ff5184bf31e21eb5e2af467bd63a24
|
|
4
|
+
data.tar.gz: 79f586268536dfc6c6c21ffdaf3f3f38a9adfadd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae1c2d11044288d7d1e0dc4036873247c35e969c35e3f64550ee52c629ca48b0cce081dd2e58fe92af8c8b8f51051ffd77df7c032298aad26c138b6756abc485
|
|
7
|
+
data.tar.gz: 72561e7f4040d2f2395c61e13c5e6516146014f1d1d2fdb8f630806590a5da5b5f7c478281d3e7bde24fad8f199dceda7395e13f15bc6dcc64250cb30d4a05fa
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.1
|
|
1
|
+
1.4.1
|
|
@@ -21,16 +21,17 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
22
22
|
spec.require_paths = ["lib"]
|
|
23
23
|
|
|
24
|
-
spec.add_runtime_dependency "addressable"
|
|
24
|
+
spec.add_runtime_dependency "addressable" , "> 2.3.5"
|
|
25
25
|
spec.add_runtime_dependency "escape_utils" , "> 1.0.0"
|
|
26
|
-
spec.add_runtime_dependency "unf"
|
|
26
|
+
spec.add_runtime_dependency "unf" , "> 0.1.3"
|
|
27
27
|
spec.add_runtime_dependency "htmlentities" , ">= 4.3.2"
|
|
28
|
+
spec.add_runtime_dependency "multi_json" , "> 1.10.0"
|
|
29
|
+
spec.add_runtime_dependency "oj" , "> 2.10.1"
|
|
28
30
|
|
|
29
31
|
spec.add_development_dependency "pry" , ">= 0.9"
|
|
30
32
|
spec.add_development_dependency "rake" , ">= 10.3"
|
|
31
33
|
spec.add_development_dependency "bundler" , ">= 1.5"
|
|
32
34
|
spec.add_development_dependency "bacon" , ">= 1.0"
|
|
33
35
|
spec.add_development_dependency "Bacon_Colored" , ">= 0.1"
|
|
34
|
-
spec.add_development_dependency "multi_json" , ">= 1.10"
|
|
35
36
|
spec.add_development_dependency "sanitize" , ">= 3.0.1"
|
|
36
37
|
end
|
data/lib/escape_escape_escape.rb
CHANGED
|
@@ -22,6 +22,14 @@ require 'cgi' # Don't use URI.escape because it does not escape all invalid char
|
|
|
22
22
|
require "addressable/uri"
|
|
23
23
|
# ======================
|
|
24
24
|
|
|
25
|
+
require 'oj'
|
|
26
|
+
require 'multi_json'
|
|
27
|
+
|
|
28
|
+
Oj.default_options = {:mode=>:strict}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
25
33
|
def Escape_Escape_Escape s
|
|
26
34
|
Escape_Escape_Escape.escape(s)
|
|
27
35
|
end
|
|
@@ -35,16 +43,20 @@ class Escape_Escape_Escape
|
|
|
35
43
|
|
|
36
44
|
CODER = HTMLEntities.new(:xhtml1)
|
|
37
45
|
|
|
38
|
-
Invalid
|
|
39
|
-
Invalid_HREF
|
|
40
|
-
|
|
41
|
-
Invalid_Type
|
|
46
|
+
Invalid = Class.new(StandardError)
|
|
47
|
+
Invalid_HREF = Class.new(Invalid)
|
|
48
|
+
Invalid_Relative_HREF = Class.new(Invalid_HREF)
|
|
49
|
+
Invalid_Type = Class.new(Invalid)
|
|
42
50
|
|
|
43
51
|
TAG_PATTERN = /\A[a-z]([a-z0-9\_]{0,}[a-z]{1,})?\z/i
|
|
44
52
|
|
|
45
|
-
VALID_CSS_VALUE
|
|
46
|
-
VALID_CSS_SELECTOR
|
|
47
|
-
VALID_CSS_ATTR
|
|
53
|
+
VALID_CSS_VALUE = /\A[a-z0-9\;\-\_\#\ ]+\z/i
|
|
54
|
+
VALID_CSS_SELECTOR = /\A[a-z0-9\#\:\_\-\.\ ]+\z/i
|
|
55
|
+
VALID_CSS_ATTR = /\A[a-z0-9-]+\z/i
|
|
56
|
+
VALID_CSS_CLASS_NAME = /\A[a-z0-9\_]+\z/i
|
|
57
|
+
|
|
58
|
+
VALID_HTML_ID = /\A[a-z][0-9a-z_]*\z/;
|
|
59
|
+
VALID_HTML_TAG = /\A[a-z][0-9a-z_]*\z/;
|
|
48
60
|
|
|
49
61
|
INVALID_FILE_NAME_CHARS = /[^a-z0-9\_\.]{1,}/i
|
|
50
62
|
|
|
@@ -58,9 +70,6 @@ class Escape_Escape_Escape
|
|
|
58
70
|
NL = "\n";
|
|
59
71
|
SPACES = /\ +/;
|
|
60
72
|
|
|
61
|
-
VALID_HTML_ID = /\A[0-9a-z_]+\z/i;
|
|
62
|
-
VALID_HTML_TAG = /\A[0-9a-z_]+\z/i;
|
|
63
|
-
|
|
64
73
|
REPEATING_DOTS = /\.{1,}/
|
|
65
74
|
|
|
66
75
|
# === MULTI_CONTROL_CHARS: ==================================
|
|
@@ -197,6 +206,14 @@ class Escape_Escape_Escape
|
|
|
197
206
|
end
|
|
198
207
|
end
|
|
199
208
|
|
|
209
|
+
def relative_href raw_str
|
|
210
|
+
str = Escape_Escape_Escape.decode_html href(raw_str)
|
|
211
|
+
uri = URI.parse(str)
|
|
212
|
+
fail( Invalid_Relative_HREF, "Is not relative: #{str}" ) if uri.scheme
|
|
213
|
+
|
|
214
|
+
Escape_Escape_Escape.html str
|
|
215
|
+
end
|
|
216
|
+
|
|
200
217
|
# ===============================================
|
|
201
218
|
# HTML
|
|
202
219
|
# ===============================================
|
|
@@ -222,6 +239,11 @@ class Escape_Escape_Escape
|
|
|
222
239
|
EOF
|
|
223
240
|
}
|
|
224
241
|
|
|
242
|
+
def css_class_name val
|
|
243
|
+
return val if val.is_a?(String) && val[VALID_CSS_CLASS_NAME]
|
|
244
|
+
fail(Invalid, "CSS class name: #{val.inspect}")
|
|
245
|
+
end
|
|
246
|
+
|
|
225
247
|
# ===============================================
|
|
226
248
|
# A better alternative than "Rack::Utils.escape_html". Escapes
|
|
227
249
|
# various characters (including '&', '<', '>', and both quotation mark types)
|
|
@@ -231,10 +253,32 @@ class Escape_Escape_Escape
|
|
|
231
253
|
# Text has to be UTF-8 before encoding, according to HTMLEntities gem.
|
|
232
254
|
# Therefore, all text is run through <plaintext> before encoding.
|
|
233
255
|
# ===============================================
|
|
234
|
-
def html
|
|
256
|
+
def html raw_text
|
|
235
257
|
EscapeUtils.escape_html(decode_html(raw_text))
|
|
236
258
|
end # === def html
|
|
237
259
|
|
|
260
|
+
def html_tag raw_o
|
|
261
|
+
case raw_o
|
|
262
|
+
when String, Symbol
|
|
263
|
+
str = raw_o.to_s.downcase
|
|
264
|
+
return str.to_sym if str[VALID_HTML_TAG]
|
|
265
|
+
raise Invalid, "Invalid chars: #{raw_o.inspect}"
|
|
266
|
+
else
|
|
267
|
+
fail TypeError, "Not a String or Symbol: #{raw_o.inspect}"
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def html_id raw_o
|
|
272
|
+
case raw_o
|
|
273
|
+
when String, Symbol
|
|
274
|
+
str = raw_o.to_s.downcase
|
|
275
|
+
return str.to_sym if str[VALID_HTML_ID]
|
|
276
|
+
raise Invalid, "Invalid chars: #{raw_o.inspect}"
|
|
277
|
+
else
|
|
278
|
+
fail TypeError, "Not a String or Symbol: #{raw_o.inspect}"
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
238
282
|
def escape o, method_name = :html
|
|
239
283
|
if o.kind_of? Hash
|
|
240
284
|
return(
|
|
@@ -253,6 +297,24 @@ class Escape_Escape_Escape
|
|
|
253
297
|
fail Invalid, "Not a String, Number, Array, or Hash"
|
|
254
298
|
end # === def
|
|
255
299
|
|
|
300
|
+
def json_encode o
|
|
301
|
+
case o
|
|
302
|
+
when Array
|
|
303
|
+
Oj.dump(o, mode: :strict)
|
|
304
|
+
else
|
|
305
|
+
fail Invalid, "Not an Array: #{o.inspect}"
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def json_decode o
|
|
310
|
+
case o
|
|
311
|
+
when String
|
|
312
|
+
Oj.strict_load clean_utf8(o)
|
|
313
|
+
else
|
|
314
|
+
fail Invalid, "Not a String: #{o.inspect}"
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
256
318
|
end # === class self ===
|
|
257
319
|
|
|
258
320
|
end # === class Escape_Escape_Escape ===
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
it 'raises Invalid if has invalid chars:'
|
|
4
|
+
input 'k k'
|
|
5
|
+
raises Escape_Escape_Escape::Invalid, /k k/
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
it 'raises Invalid if has invalid chars:'
|
|
9
|
+
input 'k&k'
|
|
10
|
+
raises Escape_Escape_Escape::Invalid, /k&k/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
it 'returns String if valid:'
|
|
14
|
+
input 'my_name'
|
|
15
|
+
output 'my_name'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
it 'raises Invalid if it contains a dash:'
|
|
19
|
+
input 'my-name'
|
|
20
|
+
raises Escape_Escape_Escape::Invalid, /my-name/
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
it 'raises Invalid if it has invalid chars:'
|
|
4
|
+
input 'a*'
|
|
5
|
+
raises Escape_Escape_Escape::Invalid, /a\*/
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
it 'returns a Symbol if a String is passed:'
|
|
9
|
+
input 'a'
|
|
10
|
+
output :a
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
it 'returns a Symbol if a Symbol is passed:'
|
|
14
|
+
input :a
|
|
15
|
+
output :a
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
it 'downcases if passed a String:'
|
|
19
|
+
input 'My_Id'
|
|
20
|
+
output :my_id
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
it 'downcases if passed a Symbol:'
|
|
24
|
+
input :My_Id
|
|
25
|
+
output :my_id
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
it 'raises Invalid if it begins with a number'
|
|
29
|
+
input '0a'
|
|
30
|
+
raises Escape_Escape_Escape::Invalid, /0a/
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
it 'raises Invalid if it contains a dash'
|
|
34
|
+
input 'my-id'
|
|
35
|
+
raises Escape_Escape_Escape::Invalid, /my-id/
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
it "raises Invalid if tag has invalid chars:"
|
|
5
|
+
input "a("
|
|
6
|
+
raises Escape_Escape_Escape::Invalid, /a\(/
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
it "raises Invalid if tag starts w/ Numeric:"
|
|
10
|
+
input '9a'
|
|
11
|
+
raises Escape_Escape_Escape::Invalid, /9a/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
it "allows numbers:"
|
|
15
|
+
input :a9
|
|
16
|
+
output :a9
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
it "allows underscores:"
|
|
20
|
+
input :a_a
|
|
21
|
+
output :a_a
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
it "downcases the tag:"
|
|
25
|
+
input "DiV"
|
|
26
|
+
output :div
|
|
27
|
+
|
|
28
|
+
it "downcases the tag:"
|
|
29
|
+
input :DiV
|
|
30
|
+
output :div
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
it "returns a Symbol if passed a Symbol:"
|
|
34
|
+
input :footer
|
|
35
|
+
output :footer
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
it "returns a Symbol if passed a String:"
|
|
39
|
+
input 'footeR'
|
|
40
|
+
output :footer
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
it "raises Invalid_HREF if it has a javascript scheme:"
|
|
4
|
+
input "javascript://something"
|
|
5
|
+
raises Escape_Escape_Escape::Invalid_HREF, /javascript/
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
it "raises Invalid_Relative_HREF if it has a http scheme:"
|
|
9
|
+
input "http://www.google.com"
|
|
10
|
+
raises Escape_Escape_Escape::Invalid_Relative_HREF, /google/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
it "returns string if it is relative:"
|
|
14
|
+
input "/file.jpg"
|
|
15
|
+
output "/file.jpg"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
it "returns string if it is relative:"
|
|
19
|
+
input "file/file/file.jpg"
|
|
20
|
+
output "file/file/file.jpg"
|
|
21
|
+
|
|
22
|
+
it "escapes slashes:"
|
|
23
|
+
input "file/file.jpg"
|
|
24
|
+
output "file/file.jpg"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
it 'strips unprintable chars'
|
|
3
|
+
input %^["a\u2029\u2028b"]^
|
|
4
|
+
output ["ab"]
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
it 'raises Oj::ParseError if invalid JSON:'
|
|
8
|
+
input 'a'
|
|
9
|
+
raises Oj::ParseError, /unexpected character/
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
it 'raises Invalid if not a String:'
|
|
13
|
+
input 1
|
|
14
|
+
raises Escape_Escape_Escape::Invalid, /1/
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
it 'uses :strict_load'
|
|
18
|
+
input Oj.dump(Object.new, :mode=>:object)
|
|
19
|
+
output({"^o" => "Object"})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
it 'raises TypeError if it encounters an unallowed Object'
|
|
3
|
+
input [Object.new]
|
|
4
|
+
raises TypeError, /Failed to dump Object Object/
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
it 'raises Invalid if not an Array:'
|
|
8
|
+
input( {'a'=>'hello'} )
|
|
9
|
+
raises Escape_Escape_Escape::Invalid, /Not an Array/
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
it 'raises Invalid if not an Array:'
|
|
13
|
+
input 'a'
|
|
14
|
+
raises Escape_Escape_Escape::Invalid, /Not an Array/
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
it 'raises Invalid if not an Array:'
|
|
18
|
+
input 1
|
|
19
|
+
raises Escape_Escape_Escape::Invalid, /Not an Array: 1/
|
|
@@ -46,11 +46,11 @@ class It_Dsl
|
|
|
46
46
|
|
|
47
47
|
def << t
|
|
48
48
|
if !args.empty?
|
|
49
|
-
fail "Unknown values pending for: #{tests.last[:describe]}: #{args.inspect}
|
|
49
|
+
fail "Unknown values pending for: #{tests.last[:describe]}: #{args.inspect}"
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
t[:it] = if t[:it].strip[/:\z/]
|
|
53
|
-
"#{t[:it]} #{t[:input]}"
|
|
53
|
+
"#{t[:it]} #{t[:input].inspect}"
|
|
54
54
|
else
|
|
55
55
|
t[:it]
|
|
56
56
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: escape_escape_escape
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1
|
|
4
|
+
version: 1.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- da99
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-09-
|
|
11
|
+
date: 2014-09-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: addressable
|
|
@@ -66,6 +66,34 @@ dependencies:
|
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: 4.3.2
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: multi_json
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 1.10.0
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: 1.10.0
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: oj
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: 2.10.1
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: 2.10.1
|
|
69
97
|
- !ruby/object:Gem::Dependency
|
|
70
98
|
name: pry
|
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -136,20 +164,6 @@ dependencies:
|
|
|
136
164
|
- - ">="
|
|
137
165
|
- !ruby/object:Gem::Version
|
|
138
166
|
version: '0.1'
|
|
139
|
-
- !ruby/object:Gem::Dependency
|
|
140
|
-
name: multi_json
|
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
|
142
|
-
requirements:
|
|
143
|
-
- - ">="
|
|
144
|
-
- !ruby/object:Gem::Version
|
|
145
|
-
version: '1.10'
|
|
146
|
-
type: :development
|
|
147
|
-
prerelease: false
|
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
-
requirements:
|
|
150
|
-
- - ">="
|
|
151
|
-
- !ruby/object:Gem::Version
|
|
152
|
-
version: '1.10'
|
|
153
167
|
- !ruby/object:Gem::Dependency
|
|
154
168
|
name: sanitize
|
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -181,12 +195,18 @@ files:
|
|
|
181
195
|
- specs/as_ruby/0001-html.rb
|
|
182
196
|
- specs/as_ruby/0002-decode_html.rb
|
|
183
197
|
- specs/as_ruby/0003-css_attr.rb
|
|
198
|
+
- specs/as_ruby/0003-css_class_name.rb
|
|
184
199
|
- specs/as_ruby/0003-css_selector.rb
|
|
185
200
|
- specs/as_ruby/0003-css_value.rb
|
|
186
201
|
- specs/as_ruby/0004-==.rb
|
|
202
|
+
- specs/as_ruby/0005-html_id.rb
|
|
203
|
+
- specs/as_ruby/0005-html_tag.rb
|
|
187
204
|
- specs/as_ruby/0020-href.rb
|
|
205
|
+
- specs/as_ruby/0021-relative_href.rb
|
|
188
206
|
- specs/as_ruby/0030-clean_utf8.rb
|
|
189
207
|
- specs/as_ruby/0040-escape.rb
|
|
208
|
+
- specs/as_ruby/0050-json_decode.rb
|
|
209
|
+
- specs/as_ruby/0051-json_encode.rb
|
|
190
210
|
- specs/escape_escape_escape.rb
|
|
191
211
|
- specs/lib/helpers.rb
|
|
192
212
|
homepage: https://github.com/da99/escape_escape_escape
|