escape_utils 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.2 (February 28th, 2013)
4
+ * fix rbx compatibility
5
+ * add EscapeUtils.html_safe_string_class
6
+ * add EscapeUtils.escape_html_as_html_safe
7
+
8
+ ## 0.3.1 (February 26th, 2013)
9
+ * fixed compilation on Windows
10
+
3
11
  ## 0.3.0 (February 26th, 2013)
4
12
  * add xml escaping support
5
13
  * in Ruby 1.9 - escape_utils now requires the input string be UTF-8
@@ -6,10 +6,6 @@
6
6
  #include <ruby.h>
7
7
  #include "houdini.h"
8
8
 
9
- #if RB_CVAR_SET_ARITY == 4
10
- # define rb_cvar_set(a,b,c) rb_cvar_set(a,b,c,0)
11
- #endif
12
-
13
9
  #ifdef HAVE_RUBY_ENCODING_H
14
10
  #include <ruby/encoding.h>
15
11
  static VALUE rb_eEncodingCompatibilityError;
@@ -48,22 +44,34 @@ static void check_utf8_encoding(VALUE str) {}
48
44
  typedef int (*houdini_cb)(gh_buf *, const uint8_t *, size_t);
49
45
 
50
46
  static VALUE rb_mEscapeUtils;
47
+ static ID ID_at_html_safe, ID_new;
51
48
 
52
49
  /**
53
50
  * html_secure instance variable
54
51
  */
55
- static ID rb_html_secure;
56
52
  static int g_html_secure = 1;
57
53
 
58
- static VALUE rb_eu_get_html_secure(VALUE self)
54
+ static VALUE rb_eu_set_html_secure(VALUE self, VALUE val)
59
55
  {
60
- return rb_cvar_get(self, rb_html_secure);
56
+ g_html_secure = RTEST(val);
57
+ rb_ivar_set(self, rb_intern("@html_secure"), val);
58
+ return val;
61
59
  }
62
60
 
63
- static VALUE rb_eu_set_html_secure(VALUE self, VALUE val)
61
+ /**
62
+ * html_safe_string_class instance variable
63
+ */
64
+ static VALUE rb_html_safe_string_class;
65
+
66
+ static VALUE rb_eu_set_html_safe_string_class(VALUE self, VALUE val)
64
67
  {
65
- g_html_secure = RTEST(val);
66
- rb_cvar_set(self, rb_html_secure, val);
68
+ Check_Type(val, T_CLASS);
69
+
70
+ if (rb_funcall(val, rb_intern("<="), 1, rb_cString) == Qnil)
71
+ rb_raise(rb_eArgError, "%s must be a descendent of String", rb_class2name(val));
72
+
73
+ rb_html_safe_string_class = val;
74
+ rb_ivar_set(self, rb_intern("@html_safe_string_class"), val);
67
75
  return val;
68
76
  }
69
77
 
@@ -94,6 +102,37 @@ rb_eu__generic(VALUE str, houdini_cb do_escape)
94
102
  /**
95
103
  * HTML methods
96
104
  */
105
+ static VALUE rb_eu_escape_html_as_html_safe(VALUE self, VALUE str)
106
+ {
107
+ VALUE result;
108
+ int secure = g_html_secure;
109
+ gh_buf buf = GH_BUF_INIT;
110
+
111
+ Check_Type(str, T_STRING);
112
+ check_utf8_encoding(str);
113
+
114
+ if (houdini_escape_html0(&buf, (const uint8_t *)RSTRING_PTR(str), RSTRING_LEN(str), secure)) {
115
+ result = eu_new_str(buf.ptr, buf.size);
116
+ gh_buf_free(&buf);
117
+ } else {
118
+ #ifdef RBASIC
119
+ result = rb_str_dup(str);
120
+ #else
121
+ result = str;
122
+ #endif
123
+ }
124
+
125
+ #ifdef RBASIC
126
+ RBASIC(result)->klass = rb_html_safe_string_class;
127
+ #else
128
+ result = rb_funcall(rb_html_safe_string_class, ID_new, 1, result);
129
+ #endif
130
+
131
+ rb_ivar_set(result, ID_at_html_safe, Qtrue);
132
+
133
+ return result;
134
+ }
135
+
97
136
  static VALUE rb_eu_escape_html(int argc, VALUE *argv, VALUE self)
98
137
  {
99
138
  VALUE str, rb_secure;
@@ -181,12 +220,14 @@ static VALUE rb_eu_unescape_uri(VALUE self, VALUE str)
181
220
  void Init_escape_utils()
182
221
  {
183
222
  #ifdef HAVE_RUBY_ENCODING_H
184
- VALUE rb_cEncoding = rb_const_get(rb_cObject, rb_intern("Encoding"));
185
223
  rb_eEncodingCompatibilityError = rb_const_get(rb_cEncoding, rb_intern("CompatibilityError"));
186
224
  #endif
187
225
 
226
+ ID_new = rb_intern("new");
227
+ ID_at_html_safe = rb_intern("@html_safe");
188
228
  rb_mEscapeUtils = rb_define_module("EscapeUtils");
189
229
 
230
+ rb_define_method(rb_mEscapeUtils, "escape_html_as_html_safe", rb_eu_escape_html_as_html_safe, 1);
190
231
  rb_define_method(rb_mEscapeUtils, "escape_html", rb_eu_escape_html, -1);
191
232
  rb_define_method(rb_mEscapeUtils, "unescape_html", rb_eu_unescape_html, 1);
192
233
  rb_define_method(rb_mEscapeUtils, "escape_xml", rb_eu_escape_xml, 1);
@@ -197,9 +238,7 @@ void Init_escape_utils()
197
238
  rb_define_method(rb_mEscapeUtils, "escape_uri", rb_eu_escape_uri, 1);
198
239
  rb_define_method(rb_mEscapeUtils, "unescape_uri", rb_eu_unescape_uri, 1);
199
240
 
200
- rb_define_singleton_method(rb_mEscapeUtils, "html_secure", rb_eu_get_html_secure, 0);
201
241
  rb_define_singleton_method(rb_mEscapeUtils, "html_secure=", rb_eu_set_html_secure, 1);
202
-
203
- rb_html_secure = rb_intern("@@html_secure");
242
+ rb_define_singleton_method(rb_mEscapeUtils, "html_safe_string_class=", rb_eu_set_html_safe_string_class, 1);
204
243
  }
205
244
 
@@ -1,17 +1,6 @@
1
- # encoding: UTF-8
2
1
  require 'mkmf'
3
- require 'rbconfig'
4
2
 
5
3
  $CFLAGS << ' -Wall -funroll-loops'
6
4
  $CFLAGS << ' -Wextra -O0 -ggdb3' if ENV['DEBUG']
7
5
 
8
- if try_compile(<<SRC)
9
- #include <ruby.h>
10
- int main(void) { rb_cvar_set(Qnil, Qnil, Qnil); return 0; }
11
- SRC
12
- $CFLAGS << " -DRB_CVAR_SET_ARITY=3 "
13
- else
14
- $CFLAGS << " -DRB_CVAR_SET_ARITY=4 "
15
- end
16
-
17
6
  create_makefile("escape_utils/escape_utils")
@@ -7,7 +7,16 @@ module EscapeUtils
7
7
  # turn on/off the escaping of the '/' character during HTML escaping
8
8
  # Escaping '/' is recommended by the OWASP - http://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content
9
9
  # This is because quotes around HTML attributes are optional in most/all modern browsers at the time of writing (10/15/2010)
10
- @@html_secure = true
10
+ def self.html_secure
11
+ @html_secure
12
+ end
13
+ self.html_secure = true
14
+
15
+ # Default String class to return from HTML escaping
16
+ def self.html_safe_string_class
17
+ @html_safe_string_class
18
+ end
19
+ self.html_safe_string_class = String
11
20
 
12
21
  autoload :HtmlSafety, 'escape_utils/html_safety'
13
22
  end
@@ -1,3 +1,3 @@
1
1
  module EscapeUtils
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -1,5 +1,8 @@
1
1
  require File.expand_path("../../helper", __FILE__)
2
2
 
3
+ class MyCustomHtmlSafeString < String
4
+ end
5
+
3
6
  class HtmlEscapeTest < MiniTest::Unit::TestCase
4
7
  def test_escape_basic_html_with_secure
5
8
  assert_equal "&lt;some_tag&#47;&gt;", EscapeUtils.escape_html("<some_tag/>")
@@ -36,6 +39,36 @@ class HtmlEscapeTest < MiniTest::Unit::TestCase
36
39
  assert_equal str.object_id, EscapeUtils.escape_html(str).object_id
37
40
  end
38
41
 
42
+ def test_html_safe_escape_default_works
43
+ str = EscapeUtils.escape_html_as_html_safe('foobar')
44
+ assert_equal 'foobar', str
45
+ end
46
+
47
+ def test_returns_custom_string_class
48
+ klass_before = EscapeUtils.html_safe_string_class
49
+ EscapeUtils.html_safe_string_class = MyCustomHtmlSafeString
50
+
51
+ str = EscapeUtils.escape_html_as_html_safe('foobar')
52
+ assert_equal 'foobar', str
53
+ assert_equal MyCustomHtmlSafeString, str.class
54
+ assert_equal true, str.instance_variable_get(:@html_safe)
55
+ ensure
56
+ EscapeUtils.html_safe_string_class = klass_before
57
+ end
58
+
59
+ def test_html_safe_string_class_descends_string
60
+ assert_raises ArgumentError do
61
+ EscapeUtils.html_safe_string_class = Hash
62
+ end
63
+
64
+ begin
65
+ EscapeUtils.html_safe_string_class = String
66
+ EscapeUtils.html_safe_string_class = MyCustomHtmlSafeString
67
+ rescue ArgumentError => e
68
+ assert_nil e, "#{e.class.name} raised, expected nothing"
69
+ end
70
+ end
71
+
39
72
  if RUBY_VERSION =~ /^1.9/
40
73
  def test_utf8_or_ascii_input_only
41
74
  str = "<b>Bourbon & Branch</b>"
@@ -58,4 +91,4 @@ class HtmlEscapeTest < MiniTest::Unit::TestCase
58
91
  assert_equal Encoding.find('UTF-8'), EscapeUtils.escape_html(str).encoding
59
92
  end
60
93
  end
61
- end
94
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: escape_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.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: 2013-02-27 00:00:00.000000000 Z
12
+ date: 2013-02-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler