[前][次][番号順一覧][スレッド一覧]

ruby-changes:63109

From: Jean <ko1@a...>
Date: Fri, 25 Sep 2020 17:29:02 +0900 (JST)
Subject: [ruby-changes:63109] e1659af372 (master): Add an option to escape forward slash character

https://git.ruby-lang.org/ruby.git/commit/?id=e1659af372

From e1659af3724e2320e9f2f2bd7cf602686e8aa523 Mon Sep 17 00:00:00 2001
From: Jean Boussier <jean.boussier@g...>
Date: Thu, 30 Jan 2020 12:48:05 +0100
Subject: Add an option to escape forward slash character

Squashed commit of the following:

commit 26d181059989279a79c433cedcd893b4f52e42ee
Author: Francois Chagnon <francois.chagnon@j...>
Date:   Tue Sep 15 21:17:34 2015 +0000

    add config options for escape_slash

commit fa282334051b16df91ca097dd7304b46f3bc7719
Author: Francois Chagnon <francois.chagnon@j...>
Date:   Mon Feb 9 21:09:33 2015 +0000

    add forward slash to escape character

diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c
index 749efaf..80d1ca7 100644
--- a/ext/json/generator/generator.c
+++ b/ext/json/generator/generator.c
@@ -22,7 +22,7 @@ static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before, https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L22
           i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
           i_pack, i_unpack, i_create_id, i_extend, i_key_p,
           i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth,
-          i_buffer_initial_length, i_dup;
+          i_buffer_initial_length, i_dup, i_escape_slash;
 
 /*
  * Copyright 2001-2004 Unicode, Inc.
@@ -130,7 +130,7 @@ static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L130
 
 /* Converts string to a JSON string in FBuffer buffer, where all but the ASCII
  * and control characters are JSON escaped. */
-static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
+static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash)
 {
     const UTF8 *source = (UTF8 *) RSTRING_PTR(string);
     const UTF8 *sourceEnd = source + RSTRING_LEN(string);
@@ -180,6 +180,11 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L180
                         case '"':
                             fbuffer_append(buffer, "\\\"", 2);
                             break;
+                        case '/':
+                            if(escape_slash) {
+                                fbuffer_append(buffer, "\\/", 2);
+                                break;
+                            }
                         default:
                             fbuffer_append_char(buffer, (char)ch);
                             break;
@@ -229,7 +234,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L234
  * characters required by the JSON standard are JSON escaped. The remaining
  * characters (should be UTF8) are just passed through and appended to the
  * result. */
-static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
+static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash)
 {
     const char *ptr = RSTRING_PTR(string), *p;
     unsigned long len = RSTRING_LEN(string), start = 0, end = 0;
@@ -280,6 +285,12 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L285
                     escape =  "\\\"";
                     escape_len = 2;
                     break;
+                case '/':
+                    if(escape_slash) {
+                        escape = "\\/";
+                        escape_len = 2;
+                        break;
+                    }
                 default:
                     {
                         unsigned short clen = 1;
@@ -716,6 +727,8 @@ static VALUE cState_configure(VALUE self, VALUE opts) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L727
     state->allow_nan = RTEST(tmp);
     tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
     state->ascii_only = RTEST(tmp);
+    tmp = rb_hash_aref(opts, ID2SYM(i_escape_slash));
+    state->escape_slash = RTEST(tmp);
     return self;
 }
 
@@ -750,6 +763,7 @@ static VALUE cState_to_h(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L763
     rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
     rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
     rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
+    rb_hash_aset(result, ID2SYM(i_escape_slash), state->escape_slash ? Qtrue : Qfalse);
     rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
     rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
     return result;
@@ -934,9 +948,9 @@ static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_S https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L948
     }
 #endif
     if (state->ascii_only) {
-        convert_UTF8_to_JSON_ASCII(buffer, obj);
+        convert_UTF8_to_JSON_ASCII(buffer, obj, state->escape_slash);
     } else {
-        convert_UTF8_to_JSON(buffer, obj);
+        convert_UTF8_to_JSON(buffer, obj, state->escape_slash);
     }
     fbuffer_append_char(buffer, '"');
 }
@@ -1378,6 +1392,31 @@ static VALUE cState_max_nesting_set(VALUE self, VALUE depth) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L1392
 }
 
 /*
+ * call-seq: escape_slash
+ *
+ * If this boolean is true, the forward slashes will be escaped in
+ * the json output.
+ */
+static VALUE cState_escape_slash(VALUE self)
+{
+    GET_STATE(self);
+    return state->escape_slash ? Qtrue : Qfalse;
+}
+
+/*
+ * call-seq: escape_slash=(depth)
+ *
+ * This sets whether or not the forward slashes will be escaped in
+ * the json output.
+ */
+static VALUE cState_escape_slash_set(VALUE self, VALUE enable)
+{
+    GET_STATE(self);
+    state->escape_slash = RTEST(enable);
+    return Qnil;
+}
+
+/*
  * call-seq: allow_nan?
  *
  * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
@@ -1489,6 +1528,9 @@ void Init_generator(void) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L1528
     rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
     rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
     rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
+    rb_define_method(cState, "escape_slash", cState_escape_slash, 0);
+    rb_define_method(cState, "escape_slash?", cState_escape_slash, 0);
+    rb_define_method(cState, "escape_slash=", cState_escape_slash_set, 1);
     rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
     rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
     rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
@@ -1545,6 +1587,7 @@ void Init_generator(void) https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.c#L1587
     i_object_nl = rb_intern("object_nl");
     i_array_nl = rb_intern("array_nl");
     i_max_nesting = rb_intern("max_nesting");
+    i_escape_slash = rb_intern("escape_slash");
     i_allow_nan = rb_intern("allow_nan");
     i_ascii_only = rb_intern("ascii_only");
     i_depth = rb_intern("depth");
diff --git a/ext/json/generator/generator.h b/ext/json/generator/generator.h
index c367a62..3ebd622 100644
--- a/ext/json/generator/generator.h
+++ b/ext/json/generator/generator.h
@@ -49,8 +49,8 @@ static const UTF32 halfMask = 0x3FFUL; https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.h#L49
 static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length);
 static void unicode_escape(char *buf, UTF16 character);
 static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character);
-static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string);
-static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string);
+static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash);
+static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash);
 static char *fstrndup(const char *ptr, unsigned long len);
 
 /* ruby api and some helpers */
@@ -72,6 +72,7 @@ typedef struct JSON_Generator_StateStruct { https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.h#L72
     long max_nesting;
     char allow_nan;
     char ascii_only;
+    char escape_slash;
     long depth;
     long buffer_initial_length;
 } JSON_Generator_State;
@@ -150,6 +151,8 @@ static VALUE cState_allow_nan_p(VALUE self); https://github.com/ruby/ruby/blob/trunk/ext/json/generator/generator.h#L151
 static VALUE cState_ascii_only_p(VALUE self);
 static VALUE cState_depth(VALUE self);
 static VALUE cState_depth_set(VALUE self, VALUE depth);
+static VALUE cState_escape_slash(VALUE self);
+static VALUE cState_escape_slash_set(VALUE self, VALUE depth);
 static FBuffer *cState_prepare_buffer(VALUE self);
 #ifndef ZALLOC
 #define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb
index 991d760..8e45b51 100644
--- a/ext/json/lib/json/common.rb
+++ b/ext/json/lib/json/common.rb
@@ -593,12 +593,13 @@ module JSON https://github.com/ruby/ruby/blob/trunk/ext/json/lib/json/common.rb#L593
     # Sets or returns the default options for the JSON.dump method.
     # Initially:
     #   opts = JSON.dump_default_options
-    #   opts # => {:max_nesting=>false, :allow_nan=>true}
+    #   opts # => {:max_nesting=>false, :allow_nan=>true, :escape_slash=>false}
     attr_accessor :dump_default_options
   end
   self.dump_default_options = {
     :max_nesting => false,
     :allow_nan   => true,
+    :escape_slash => false,
   }
 
   # Dumps _obj_ as a JSON string, i.e. calls generate on the object and returns
diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb
old mode 100644
new mode 100755
i (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]