+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
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
namespace System.Runtime.Serialization.Json
{
// FIXME: quotas check
- // FIXME: parse object content and handle __type as attribute.
class JsonReader : XmlDictionaryReader, IXmlJsonReaderInitializer, IXmlLineInfo
{
class ElementInfo
SetInput (stream, encoding, quotas, onClose);
}
+ internal bool LameSilverlightLiteralParser { get; set; }
+
// IXmlLineInfo
public bool HasLineInfo ()
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);
}
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));
}
}
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);
+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
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