escape_escape_escape 1.5.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/escape_escape_escape.rb +33 -2
- data/specs/as_ruby/0001-html.rb +5 -1
- data/specs/as_ruby/0001-num.rb +8 -0
- data/specs/as_ruby/0003-css.rb +63 -0
- data/specs/as_ruby/0040-escape.rb +4 -4
- data/specs/escape_escape_escape.rb +5 -5
- metadata +5 -4
- data/specs/as_ruby/0003-css_value.rb +0 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 251b396b4850add2712600d6167f429b59dc04cc
|
4
|
+
data.tar.gz: c17d22cac0059acd00dab01f64fccbe04daab0f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9495213354e7ff51e47cad4ee3cbba65ebe65d847dd2058c340ff9af737a2503379b3dbd655878e39adf210353c28db7c09410b758b427486e535f81e9606141
|
7
|
+
data.tar.gz: 47e43582cc487ef12e0cf4f08c756e60b82eee0a7daf070b9c6858b210926b87cc1f63db7f36b63bb6b50011f5b01ad1c562c330fcf00747ae12a39c73da6176
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.7.0
|
data/lib/escape_escape_escape.rb
CHANGED
@@ -50,10 +50,11 @@ class Escape_Escape_Escape
|
|
50
50
|
|
51
51
|
TAG_PATTERN = /\A[a-z]([a-z0-9\_]{0,}[a-z]{1,})?\z/i
|
52
52
|
|
53
|
-
VALID_CSS_VALUE = /\A[a-z0-9\;\-\_\#\,\ ]+\z/i
|
53
|
+
VALID_CSS_VALUE = /\A[a-z0-9\;\-\_\#\,\ \.]+\z/i
|
54
54
|
VALID_CSS_SELECTOR = /\A[a-z0-9\#\:\_\-\.\ ]+\z/i
|
55
55
|
VALID_CSS_ATTR = /\A[a-z0-9-]+\z/i
|
56
56
|
VALID_CSS_CLASS_NAME = /\A[a-z0-9\_]+\z/i
|
57
|
+
VALID_CSS_WIDTH = /\A[a-z0-9\ %\.]+\Z/
|
57
58
|
|
58
59
|
VALID_HTML_ID = /\A[a-z][0-9a-z_]*\z/;
|
59
60
|
VALID_HTML_TAG = /\A[a-z][0-9a-z_]*\z/;
|
@@ -225,7 +226,7 @@ class Escape_Escape_Escape
|
|
225
226
|
|
226
227
|
def decode_html raw
|
227
228
|
fail("Not a string: #{raw.inspect}") unless raw.is_a?(String)
|
228
|
-
CODER.decode clean_utf8(raw)
|
229
|
+
CODER.decode clean_utf8(raw, :spaces)
|
229
230
|
end
|
230
231
|
|
231
232
|
%w{attr selector value}.each { |name|
|
@@ -239,6 +240,31 @@ class Escape_Escape_Escape
|
|
239
240
|
EOF
|
240
241
|
}
|
241
242
|
|
243
|
+
def css *args
|
244
|
+
case
|
245
|
+
when args.size == 1
|
246
|
+
raw_name = :unknown
|
247
|
+
raw = args.first
|
248
|
+
when args.size == 2
|
249
|
+
raw_name, raw = args
|
250
|
+
else
|
251
|
+
fail ArgumentError, "Unknown args: #{args.inspect}"
|
252
|
+
end
|
253
|
+
|
254
|
+
name = raw_name.to_s.strip
|
255
|
+
clean = html(raw)
|
256
|
+
|
257
|
+
passes = case
|
258
|
+
when name['width'.freeze]
|
259
|
+
clean[VALID_CSS_WIDTH]
|
260
|
+
else
|
261
|
+
clean[VALID_CSS_VALUE]
|
262
|
+
end
|
263
|
+
|
264
|
+
fail ArgumentError, "contains invalid chars: #{raw.inspect}" unless passes
|
265
|
+
clean
|
266
|
+
end
|
267
|
+
|
242
268
|
def css_class_name val
|
243
269
|
return val if val.is_a?(String) && val[VALID_CSS_CLASS_NAME]
|
244
270
|
fail(Invalid, "CSS class name: #{val.inspect}")
|
@@ -297,6 +323,11 @@ class Escape_Escape_Escape
|
|
297
323
|
fail Invalid, "Not a String, Number, Array, or Hash"
|
298
324
|
end # === def
|
299
325
|
|
326
|
+
def num v
|
327
|
+
fail ArgumentError, "Not a Numeric: #{v.inspect}" unless v.is_a?(Numeric)
|
328
|
+
v
|
329
|
+
end
|
330
|
+
|
300
331
|
def json_encode o
|
301
332
|
case o
|
302
333
|
when Hash
|
data/specs/as_ruby/0001-html.rb
CHANGED
@@ -43,7 +43,7 @@ raises RuntimeError, /Not a string: 1/
|
|
43
43
|
|
44
44
|
it 'removes Unicode characters that do not belong in html'
|
45
45
|
input "b \u0340 \u0341 \u17a3 \u17d3 \u2028 \u2029 \u202a"
|
46
|
-
output "b"
|
46
|
+
output "b "
|
47
47
|
|
48
48
|
it "removes unprintable characters"
|
49
49
|
input "end-\u2028-\u2029-"
|
@@ -58,3 +58,7 @@ input "&soL; &SoL; /"
|
|
58
58
|
output "&soL; &SoL; /"
|
59
59
|
|
60
60
|
|
61
|
+
it "does not strip text"
|
62
|
+
input " test "
|
63
|
+
output " test "
|
64
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
it 'allows commas and spaces'
|
3
|
+
input :font, "Ubuntu, Segoe UI, Helvetica, sans-serif"
|
4
|
+
output "Ubuntu, Segoe UI, Helvetica, sans-serif"
|
5
|
+
|
6
|
+
it 'sanitizes :css :expression regardless of the case'
|
7
|
+
input :url, "eXprEssioN(alert('xss!'));"
|
8
|
+
raises ArgumentError, /contains invalid chars/
|
9
|
+
|
10
|
+
it 'sanitizes :css :expression when ( or ) is an html entity: ( )'
|
11
|
+
input 'border', "eXprEssioN(alert('xss!'))"
|
12
|
+
raises ArgumentError, /contains invalid chars/
|
13
|
+
|
14
|
+
it 'sanitizes :css :expression when ( is html entity regardless of case: &rPaR;'
|
15
|
+
input 'title', "eXprEssioN&rPaR;alert('xss!'))"
|
16
|
+
raises ArgumentError, /contains invalid chars/
|
17
|
+
|
18
|
+
it 'sanitizes css_href'
|
19
|
+
input 'css_href', "smtp://file.com/img.png"
|
20
|
+
raises ArgumentError, /contains invalid chars/
|
21
|
+
|
22
|
+
it 'sanitizes css_href event if slash is html entity: /'
|
23
|
+
input :img_url, "smtp://file.com/img.png"
|
24
|
+
raises ArgumentError, /contains invalid chars/
|
25
|
+
|
26
|
+
it 'sanitizes css_href event if slash is html entity: /'
|
27
|
+
input 'random', "smtp://file.com/img.png"
|
28
|
+
raises ArgumentError, /contains invalid chars/
|
29
|
+
|
30
|
+
|
31
|
+
it 'sanitizes css_href event if slash is html entity: /'
|
32
|
+
input "smtp://file.com/img.png"
|
33
|
+
raises ArgumentError, /contains invalid chars/
|
34
|
+
|
35
|
+
it 'sanitizes css_href with encoded slashes'
|
36
|
+
input "smtp://file.com/img.png"
|
37
|
+
raises ArgumentError, /contains invalid chars/
|
38
|
+
|
39
|
+
it 'sanitizes javascript: protocol w/js code'
|
40
|
+
input 'jAvAscript://alert()'
|
41
|
+
raises ArgumentError, /contains invalid chars/
|
42
|
+
|
43
|
+
it 'sanitizes javascript: protocol with encoded colons:'
|
44
|
+
input "javascript://alert()"
|
45
|
+
raises ArgumentError, /contains invalid chars/
|
46
|
+
|
47
|
+
it 'sanitizes javascript: protocol with encoded slashes'
|
48
|
+
input "javascript://alert()"
|
49
|
+
raises ArgumentError, /contains invalid chars/
|
50
|
+
|
51
|
+
it 'returns cleaned string'
|
52
|
+
input '1px solid #000'
|
53
|
+
output '1px solid #000'
|
54
|
+
|
55
|
+
it 'allows multiple border_width sizes: 0 0 0.5em 3px'
|
56
|
+
input 'border_width', '0 0 0.5em 3px'
|
57
|
+
output '0 0 0.5em 3px'
|
58
|
+
|
59
|
+
it 'allows % sign in border_width sizes: 0 0 0.5% 3%'
|
60
|
+
input 'border_width', '0 0 0.5% 3%'
|
61
|
+
output '0 0 0.5% 3%'
|
62
|
+
|
63
|
+
|
@@ -14,8 +14,8 @@ raises Escape_Escape_Escape::Invalid, /Not a String, Number, Array, or Hash/i
|
|
14
14
|
it 'escapes all String keys in nested objects'
|
15
15
|
input({" a >" => {" a > " => "<b>test</b>"}})
|
16
16
|
output({
|
17
|
-
"a >" => {
|
18
|
-
"a >" => "<b>test</b>"
|
17
|
+
" a >" => {
|
18
|
+
" a > " => "<b>test</b>"
|
19
19
|
}
|
20
20
|
})
|
21
21
|
|
@@ -23,8 +23,8 @@ output({
|
|
23
23
|
it 'escapes all Symbol keys in nested objects'
|
24
24
|
input({:" a > " => {:" a >" => "<b>test</b>"}})
|
25
25
|
output({
|
26
|
-
:"a >" => {
|
27
|
-
:"a >" => "<b>test</b>"
|
26
|
+
:" a > " => {
|
27
|
+
:" a >" => "<b>test</b>"
|
28
28
|
}
|
29
29
|
})
|
30
30
|
|
@@ -40,7 +40,7 @@ class It_Dsl
|
|
40
40
|
args << str
|
41
41
|
end
|
42
42
|
|
43
|
-
def input o
|
43
|
+
def input *o
|
44
44
|
args << o
|
45
45
|
end
|
46
46
|
|
@@ -99,21 +99,21 @@ It_Dsl.tests.each { |o|
|
|
99
99
|
case
|
100
100
|
|
101
101
|
when o[:describe] == :==
|
102
|
-
t[:input].should == t[:output]
|
102
|
+
t[:input].should == [t[:output]]
|
103
103
|
|
104
104
|
when t.has_key?(:output)
|
105
|
-
Escape_Escape_Escape.send(o[:describe], t[:input])
|
105
|
+
Escape_Escape_Escape.send(o[:describe], *t[:input])
|
106
106
|
.should == t[:output]
|
107
107
|
|
108
108
|
when !t.has_key?(:output) && t[:raises]
|
109
109
|
should.raise(t[:raises].first) {
|
110
|
-
Escape_Escape_Escape.send(o[:describe], t[:input])
|
110
|
+
Escape_Escape_Escape.send(o[:describe], *t[:input])
|
111
111
|
}.message.should.match(t[:raises].last)
|
112
112
|
|
113
113
|
when t.has_key?(:stack) && t[:stack].is_a?(Array)
|
114
114
|
|
115
115
|
stack = t[:stack]
|
116
|
-
actual = Escape_Escape_Escape.send(o[:describe], t[:input])
|
116
|
+
actual = Escape_Escape_Escape.send(o[:describe], *t[:input])
|
117
117
|
target = stack.pop
|
118
118
|
|
119
119
|
begin
|
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.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- da99
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -193,11 +193,12 @@ files:
|
|
193
193
|
- escape_escape_escape.gemspec
|
194
194
|
- lib/escape_escape_escape.rb
|
195
195
|
- specs/as_ruby/0001-html.rb
|
196
|
+
- specs/as_ruby/0001-num.rb
|
196
197
|
- specs/as_ruby/0002-decode_html.rb
|
198
|
+
- specs/as_ruby/0003-css.rb
|
197
199
|
- specs/as_ruby/0003-css_attr.rb
|
198
200
|
- specs/as_ruby/0003-css_class_name.rb
|
199
201
|
- specs/as_ruby/0003-css_selector.rb
|
200
|
-
- specs/as_ruby/0003-css_value.rb
|
201
202
|
- specs/as_ruby/0004-==.rb
|
202
203
|
- specs/as_ruby/0005-html_id.rb
|
203
204
|
- specs/as_ruby/0005-html_tag.rb
|
@@ -229,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
229
230
|
version: '0'
|
230
231
|
requirements: []
|
231
232
|
rubyforge_project:
|
232
|
-
rubygems_version: 2.4.
|
233
|
+
rubygems_version: 2.4.6
|
233
234
|
signing_key:
|
234
235
|
specification_version: 4
|
235
236
|
summary: My way of escaping/encoding HTML.
|
@@ -1,56 +0,0 @@
|
|
1
|
-
|
2
|
-
it 'allows commas and spaces'
|
3
|
-
input "Ubuntu, Segoe UI, Helvetica, sans-serif"
|
4
|
-
output "Ubuntu, Segoe UI, Helvetica, sans-serif"
|
5
|
-
|
6
|
-
it 'sanitizes :css :expression regardless of the case'
|
7
|
-
input "eXprEssioN(alert('xss!'));"
|
8
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
9
|
-
|
10
|
-
it 'sanitizes :css :expression when ( or ) is an html entity: ( )'
|
11
|
-
input "eXprEssioN(alert('xss!'))"
|
12
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
13
|
-
|
14
|
-
it 'sanitizes :css :expression when ( is html entity regardless of case: &rPaR;'
|
15
|
-
input "eXprEssioN&rPaR;alert('xss!'))"
|
16
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
17
|
-
|
18
|
-
it 'sanitizes css_href'
|
19
|
-
input "smtp://file.com/img.png"
|
20
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
21
|
-
|
22
|
-
it 'sanitizes css_href event if slash is html entity: /'
|
23
|
-
input "smtp://file.com/img.png"
|
24
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
25
|
-
|
26
|
-
it 'sanitizes css_href event if slash is html entity: /'
|
27
|
-
input "smtp://file.com/img.png"
|
28
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
29
|
-
|
30
|
-
|
31
|
-
it 'sanitizes css_href event if slash is html entity: /'
|
32
|
-
input "smtp://file.com/img.png"
|
33
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
34
|
-
|
35
|
-
it 'sanitizes css_href with encoded slashes'
|
36
|
-
input "smtp://file.com/img.png"
|
37
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
38
|
-
|
39
|
-
it 'sanitizes javascript: protocol w/js code'
|
40
|
-
input 'jAvAscript://alert()'
|
41
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
42
|
-
|
43
|
-
it 'sanitizes javascript: protocol with encoded colons:'
|
44
|
-
input "javascript://alert()"
|
45
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
46
|
-
|
47
|
-
it 'sanitizes javascript: protocol with encoded slashes'
|
48
|
-
input "javascript://alert()"
|
49
|
-
raises Escape_Escape_Escape::Invalid, /contains invalid chars/
|
50
|
-
|
51
|
-
it 'returns cleaned string'
|
52
|
-
input '1px solid #000'
|
53
|
-
output '1px solid #000'
|
54
|
-
|
55
|
-
|
56
|
-
|