Bug Tracker

Opened 8 years ago

Closed 8 years ago

Last modified 7 years ago

#8320 closed bug (invalid)

parseJSON fails if data contains \' (WCF Data Services escapes single quotes)

Reported by: pitus Owned by:
Priority: low Milestone: 1.next
Component: misc Version: 1.5
Keywords: Cc:
Blocked by: Blocking:

Description

When calling jQuery.getJSON("Service.svc/Table"...) on Microsoft WCF Data Service (.NET 3.5) which returns data from Entities that contain single quotes, these quotes are escaped using a backslash, as in "Sample \'1\'" for example. This fails with a parsererror

See http://jsfiddle.net/pJgyu/6103/ or try the following:

try
{
    var o = $.parseJSON("{\"Text\":\"Sample \\'1\\'\"}");
    alert( o.Text );
}
catch( e )
{
    alert( e );
}

I have managed to fix this by adding a single quote into the escaping portion of the logic from json2.js

if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:['"\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
.replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {

Note the change from (/\\(?:["\\\/bfnrt]... to (/\\(?:['"\\\/bfnrt]...

As far as I know, this problem is with any version of jQuery.

Change History (5)

comment:1 Changed 8 years ago by jitter

Component: unfiledmisc
Priority: undecidedlow
Resolution: invalid
Status: newclosed

Thanks for taking the time to contribute to the jQuery project by writing a bug report.

This isn't a bug. Escaping single quotes inside a JSON string is neither needed or is it a valid thing to do.

You can easily verify that by:

Version 0, edited 8 years ago by jitter (next)

comment:2 Changed 8 years ago by pitus

Someone else had the same issue: http://social.technet.microsoft.com/Forums/en-US/sharepoint2010programming/thread/49136617-0a2a-4963-9e4e-6181c60ec840?prof=required

In version 1.5 this can be fixed in line 56 of jQuery-1.5.js

	rvalidescape = /\\(?:['"\\\/bfnrt]|u[0-9a-fA-F]{4})/g,

Perhaps this is NOT a bug in jQuery, but that's how Microsoft escapes single quotes so this info could prove to be useful to many developers using WFC Services.

comment:3 in reply to:  2 Changed 8 years ago by jitter

Replying to pitus:

Someone else had the same issue: http://social.technet.microsoft.com/Forums/en-US/sharepoint2010programming/thread/49136617-0a2a-4963-9e4e-6181c60ec840?prof=required

In version 1.5 this can be fixed in line 56 of jQuery-1.5.js

	rvalidescape = /\\(?:['"\\\/bfnrt]|u[0-9a-fA-F]{4})/g,

Perhaps this is NOT a bug in jQuery, but that's how Microsoft escapes single quotes so this info could prove to be useful to many developers using WFC Services.

Are you really considering using a modified version of jQuery on a production side? That's not a good idea and will cause problems later on (upgrading, maintenance, unexpected behaviors, ...)

Instead I suggest you file this as a bug to the Microsoft WCF Data Service Team. And in the mean time use a new functionality available in jQuery 1.5 to workaround this problem. Use a custom json converter.

$.ajaxSetup({
    // use custom converter to handle invalid json data
    // returned by WCF Data Service
    // fixes invalid escaped single quotes (\') in json data
    // e.g. { "foo": "bar\'tender" } --> { "foo": "bar'tender" }
    converters: {
        "text json": function( textValue ) {
            return jQuery.parseJSON( textValue.replace(/(^|[^\\])\\'/g, "$1'") );
        }
    }
});
Last edited 8 years ago by jitter (previous) (diff)

comment:4 Changed 8 years ago by pitus

Thanks for the converters example. I ended up using a slightly different version of it, one that also handles Microsoft Dates. Note that it doesn't handle Time Zone suffixes properly, as in Date(#-005)

$.ajaxSetup({
    // use custom converter to handle invalid json data returned by WCF Data Service
    // ignores invalid escaped single quotes (\') in json data
    //     e.g. { "foo": "bar\'tender" } --> { "foo": "bar'tender" }
    // also converts Microsoft Dates into actual Date objects
    //     e.g. { "\/Date(###)\/" } --> { new Date(###) }
    converters: {
        "text json": function (textValue)
        {
            return (new Function("return " + textValue
                .replace(/"\\\/Date\((-?\d*)\)\\\/"/g, "new Date($1)")
            ))();
        }
    }
});

comment:5 Changed 8 years ago by Gaute Løken <mithon81@…>

That date converter should not be applied to "text json" since it will cause any resulting json results to be parsed into a Date or string or throw an exception rather than a nested object, which is the job of mime type "application/json" aka "text json".

What you're doing here is fine and all, but you might want to apply them to "* text" instead, and control the mime type of your response, or specify it with your call to $.ajax. Finally I'd suggest you add and $ to your regex to avoid it throwing errors when your textValue contains a date as well as something else.

For a more involved discussion of how to deal with dates, feel free to have a look at this ticket: http://bugs.jquery.com/ticket/8671

Note: See TracTickets for help on using tickets.