2009-11-20 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Fri, 20 Nov 2009 06:07:51 +0000 (06:07 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Fri, 20 Nov 2009 06:07:51 +0000 (06:07 -0000)
* DataContractJsonSerializer.cs, JsonReader.cs : Silverlight uses
  LAME parser that allows object member name as *raw* string
  without double-quotes. (This also reverts the previous change.)

* DataContractJsonSerializerTest.cs : added ignored test case that
  verifies 2.1 behavior (with another case that justifies removal
  of the previous hack).

svn path=/trunk/mcs/; revision=146599

mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog
mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs
mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonReader.cs
mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog
mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs

index bb90960061328933e94ce81b2dc964c59fd9afcb..9c64b1eba344c01b101d2ecc41f8d4bf3d4161c2 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-20  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * DataContractJsonSerializer.cs, JsonReader.cs : Silverlight uses
+         LAME parser that allows object member name as *raw* string
+         without double-quotes. (This also reverts the previous change.)
+
 2009-11-12  Atsushi Enomoto  <atsushi@ximian.com>
 
        *  JsonSerializationReader.cs : reuse generic collection search
index 05e49e7b74df961f095ab414fe2ae2f337983d99..686d335c7b74ba289f125c700c38b6aaa9125c37 100644 (file)
@@ -157,43 +157,12 @@ namespace System.Runtime.Serialization.Json
                        return IsStartObject ((XmlReader) reader);
                }
 
-#if NET_2_1
-               Stream QuoteJsonKeys (Stream stream) {
-                       TextReader r = new StreamReader (stream, Encoding.UTF8);
-                       string s = r.ReadToEnd ();
-                       r.Close ();
-
-                       int pos = s.IndexOf (":");
-                       while (pos > 0) {
-                               int i = pos-1;
-                               for (; i >=0 && Char.IsWhiteSpace (s[i]); i--) {}
-                               int end = i + 1;
-                               for (; i > 0 && !Char.IsWhiteSpace (s[i-1]) && s[i-1] != ',' && s[i-1] != '{' && s[i-1] != '}' && s[i-1] != ']'; i--) {}
-                               if (s[i] != '"') {
-                                       s = s.Insert (i, "\"");
-                                       s = s.Insert (end+1, "\"");
-                                       end += 2;
-                                       pos += 2;
-                               }
-                               pos = s.IndexOf (":", pos + 1);
-                       }
-
-                       MemoryStream ms = new MemoryStream ();
-                       StreamWriter tw = new StreamWriter (ms, Encoding.UTF8);
-                       tw.Write (s);
-                       tw.Flush ();
-                       ms.Seek (0, SeekOrigin.Begin);
-                       ms.Position = 0;
-                       return ms;
-               }
-#endif
-
                public override object ReadObject (Stream stream)
                {
 #if NET_2_1
-                       using (Stream json = QuoteJsonKeys (stream)) {
-                               return ReadObject(JsonReaderWriterFactory.CreateJsonReader(json, XmlDictionaryReaderQuotas.Max));
-                       }
+                       var r = (JsonReader) JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max);
+                       r.LameSilverlightLiteralParser = true;
+                       return ReadObject(r);
 #else
                        return ReadObject (JsonReaderWriterFactory.CreateJsonReader (stream, new XmlDictionaryReaderQuotas ()));
 #endif
index 35791686459491e6cfa889405af59570b2a5185e..8954bf291c4dc37f94fe9842ee087702c9e68ad7 100644 (file)
@@ -35,7 +35,6 @@ using System.Xml;
 namespace System.Runtime.Serialization.Json
 {
        // FIXME: quotas check
-       // FIXME: parse object content and handle __type as attribute.
        class JsonReader : XmlDictionaryReader, IXmlJsonReaderInitializer, IXmlLineInfo
        {
                class ElementInfo
@@ -91,6 +90,8 @@ namespace System.Runtime.Serialization.Json
                        SetInput (stream, encoding, quotas, onClose);
                }
 
+               internal bool LameSilverlightLiteralParser { get; set; }
+
                // IXmlLineInfo
 
                public bool HasLineInfo ()
@@ -472,11 +473,13 @@ namespace System.Runtime.Serialization.Json
                                ReadEndArray ();
                                return true;
                        case '"':
-                               string s = ReadStringLiteral ();
+                               bool lame = LameSilverlightLiteralParser && ch != '"';
+                               string s = ReadStringLiteral (lame);
                                if (!objectValue && elements.Count > 0 && elements.Peek ().Type == "object") {
                                        next_element = s;
                                        SkipWhitespaces ();
-                                       Expect (':');
+                                       if (!lame)
+                                               Expect (':');
                                        SkipWhitespaces ();
                                        ReadContent (true);
                                }
@@ -516,7 +519,9 @@ namespace System.Runtime.Serialization.Json
                                        ReadNumber (ch);
                                        return true;
                                }
-                               throw XmlError (String.Format ("Unexpected token: '{0}' ({1:X04})", ch, (int) ch));
+                               if (LameSilverlightLiteralParser)
+                                       goto case '"';
+                               throw XmlError (String.Format ("Unexpected token: '{0}' ({1:X04})", (char) ch, (int) ch));
                        }
                }
 
@@ -638,13 +643,20 @@ namespace System.Runtime.Serialization.Json
                StringBuilder vb = new StringBuilder ();
 
                string ReadStringLiteral ()
+               {
+                       return ReadStringLiteral (false);
+               }
+
+               string ReadStringLiteral (bool endWithColon)
                {
                        vb.Length = 0;
                        while (true) {
                                int c = ReadChar ();
                                if (c < 0)
                                        throw XmlError ("JSON string is not closed");
-                               if (c == '"')
+                               if (c == '"' && !endWithColon)
+                                       return vb.ToString ();
+                               else if (c == ':' && endWithColon)
                                        return vb.ToString ();
                                else if (c != '\\') {
                                        vb.Append ((char) c);
index 0d062e88b16c8706c00f10a3c5e073399bdf5399..b3f7da138944b78c5c01d42620c6a1b5b8557ef0 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-20  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * DataContractJsonSerializerTest.cs : added ignored test case that
+         verifies 2.1 behavior (with another case that justifies removal
+         of the previous hack).
+
 2009-10-08  Atsushi Enomoto  <atsushi@ximian.com>
 
        * DataContractJsonSerializerTest.cs : added test for
index 0393f914611fd6eae0e6bdedd064b1a384d8f9dd..caee64a688707e572d8a9f9b620260bf3a84582d 100644 (file)
@@ -1255,6 +1255,17 @@ namespace MonoTests.System.Runtime.Serialization.Json
                        var s = Encoding.UTF8.GetString (ms.ToArray ());
                        Assert.AreEqual (@"{""Bar"":null,""Foo"":""foo""}", s, "#1");
                }
+
+               // [Test] use this case if you want to check lame silverlight parser behavior. Seealso #549756
+               public void QuotelessDeserialization ()
+               {
+                       string s1 = @"{FooMember:""value""}";
+                       var ds = new DataContractJsonSerializer (typeof (DCWithName));
+                       ds.ReadObject (new MemoryStream (Encoding.UTF8.GetBytes (s1)));
+
+                       string s2 = @"{FooMember:"" \""{dummy:string}\""""}";
+                       ds.ReadObject (new MemoryStream (Encoding.UTF8.GetBytes (s2)));
+               }
        }
 
        public class TestData