escape_utils 0.3.1 → 0.3.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.
@@ -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