Opened 12 years ago

Closed 12 years ago

#4326 closed Bugs (fixed)

Property tree json reader and writer aren't standards-compliant

Reported by: Leon Mergen <leon@…> Owned by: Sebastian Redl
Milestone: Boost 1.43.0 Component: property_tree
Version: Boost 1.44.0 Severity: Problem
Keywords: Cc: akz328@…

Description

According to the json standard, the "/" character should be escaped to "\/". The boost property tree Json parser generates an error when such an escape sequence is encountered on input, and doesn't properly escape it on output.

Here is a patch for the two files based on the 1.43 tree:

--- ./json_parser_read.hpp      2010-06-09 15:20:17.000000000 +0000
+++ ./json_parser_read.hpp.old  2010-06-09 15:24:43.000000000 +0000
@@ -128,7 +128,6 @@
                 {
                     case Ch('\"'): c.string += Ch('\"'); break;
                     case Ch('\\'): c.string += Ch('\\'); break;
-                    case Ch('/'): c.string += Ch('/'); break;
                     case Ch('0'): c.string += Ch('\0'); break;
                     case Ch('b'): c.string += Ch('\b'); break;
                     case Ch('f'): c.string += Ch('\f'); break;
@@ -247,7 +246,7 @@
                         ;

                 escape
-                    =   chset_p(detail::widen<Ch>("\"\\/0bfnrt").c_str())[typename Context::a_escape(self.c)]
+                    =   chset_p(detail::widen<Ch>("\"\\0bfnrt").c_str())[typename Context::a_escape(self.c)]
                         | 'u' >> uint_parser<unsigned long, 16, 4, 4>()[typename Context::a_unicode(self.c)]
                         ;


--- ./json_parser_write.hpp     2010-06-09 15:15:47.000000000 +0000
+++ ./json_parser_write.hpp.old 2010-06-09 15:24:51.000000000 +0000
@@ -36,7 +36,6 @@
             else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
             else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
             else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
-            else if (*b == Ch('/')) result += Ch('\\'), result += Ch('/');
             else
             {
                 if (std::isprint(*b, loc))


Change History (7)

comment:1 by Leon Mergen <leon@…>, 12 years ago

I'm sorry, the patches were backwards:

--- ./json_parser_write.hpp.old 2010-06-09 15:24:51.000000000 +0000
+++ ./json_parser_write.hpp     2010-06-09 15:15:47.000000000 +0000
@@ -36,6 +36,7 @@
             else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
             else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
             else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
+            else if (*b == Ch('/')) result += Ch('\\'), result += Ch('/');
             else
             {
                 if (std::isprint(*b, loc))



--- ./json_parser_read.hpp.old  2010-06-09 15:24:43.000000000 +0000
+++ ./json_parser_read.hpp      2010-06-09 15:20:17.000000000 +0000
@@ -128,6 +128,7 @@
                 {
                     case Ch('\"'): c.string += Ch('\"'); break;
                     case Ch('\\'): c.string += Ch('\\'); break;
+                    case Ch('/'): c.string += Ch('/'); break;
                     case Ch('0'): c.string += Ch('\0'); break;
                     case Ch('b'): c.string += Ch('\b'); break;
                     case Ch('f'): c.string += Ch('\f'); break;
@@ -246,7 +247,7 @@
                         ;

                 escape
-                    =   chset_p(detail::widen<Ch>("\"\\0bfnrt").c_str())[typename Context::a_escape(self.c)]
+                    =   chset_p(detail::widen<Ch>("\"\\/0bfnrt").c_str())[typename Context::a_escape(self.c)]
                         | 'u' >> uint_parser<unsigned long, 16, 4, 4>()[typename Context::a_unicode(self.c)]
                         ;

comment:2 by anonymous, 12 years ago

Nothing requires forward slashes to be escaped (they're not '"', '\' or control characters), but I'll adopt the part that accepts them on parsing.

comment:3 by Leon Mergen <leon@…>, 12 years ago

Well, when you go to http://json.org/ and look at the grammar at the right, it specifically says under "char" that / should be escaped to \/.

comment:4 by Leon Mergen <leon@…>, 12 years ago

http://www.ietf.org/rfc/rfc4627.txt

That standard also says that the solidus "/" should be escaped. Apparently, it is to allow embedding of JSON inside a HTML document.

This seems to be a reasonable explanation why: http://groups.google.com/group/opensocial-and-gadgets-spec/msg/f05cbf2cac48134b

comment:5 by anonymous, 12 years ago

Hmm ... makes sense.

comment:6 by Artem Kozlov <akz328@…>, 12 years ago

Cc: akz328@… added

comment:7 by Sebastian Redl, 12 years ago

Resolution: fixed
Status: newclosed

Fixed in trunk and release.

Note: See TracTickets for help on using tickets.