llList2Json() fails with strings that contain a double quote at the start and the end
under review
SuzannaLinn Resident
It returns a wrong JSON format:
string json = llList2Json(JSON_ARRAY,["\"Hello\" and \"Bye\""]);
llOwnerSay(json); // --> ["Hello" and "Bye"]
llOwnerSay(llJsonGetValue(json,[0])); // --> Bye
Adding something at the start or at the end, for instance a "." at the end, works well:
string json = llList2Json(JSON_ARRAY,["\"Hello\" and \"Bye\"."]);
llOwnerSay(json); // --> ["\"Hello\" and \"Bye\"."]
llOwnerSay(llJsonGetValue(json,[0])); // --> "Hello" and "Bye".
Log In
Maestro Linden
under review
Maestro Linden
Hi SuzannaLinn Resident, thanks for the report. I see the problem and also a solution.
This test script compares the original 2 cases, plus a 3rd case with a properly-encoded json string (double-escaping of quotation characters):
string decodeType(string type)
{
if(type == JSON_INVALID ) return "JSON_INVALID";
if(type == JSON_OBJECT ) return "JSON_OBJECT";
if(type == JSON_ARRAY ) return "JSON_ARRAY";
if(type == JSON_NUMBER ) return "JSON_NUMBER";
if(type == JSON_STRING ) return "JSON_STRING";
if(type == JSON_NULL ) return "JSON_NULL";
if(type == JSON_TRUE ) return "JSON_TRUE";
if(type == JSON_FALSE ) return "JSON_FALSE";
if(type == JSON_DELETE ) return "JSON_DELETE";
return "no idea";
}
default
{
state_entry()
{
list input = [
"\"Hello\" and \"Bye\"", // failing case
"\"Hello\" and \"Bye\".", // workaround - trailing period so not parsed as a json string
"\"\\\"Hello\\\" and \\\"Bye\\\"\"" // properly encoded json string containing double quotes
];
llOwnerSay("input list: " + llList2CSV(input));
string json = llList2Json(JSON_ARRAY, input );
llOwnerSay("output json: " + json);
integer i;
for(i = 0; i < llGetListLength(input); i++)
{
llOwnerSay("Case " + (string)i + ": '" + llList2String(input, i)
+ "' is encoded to type " + decodeType(llJsonValueType(json, [i]))
+ " with value '" + llJsonGetValue(json, [i]) + "'"
);
}
}
}
the output is:
input list: "Hello" and "Bye", "Hello" and "Bye"., "\"Hello\" and \"Bye\""
output json: ["Hello" and "Bye","\"Hello\" and \"Bye\".","\"Hello\" and \"Bye\""]
Case 0: '"Hello" and "Bye"' is encoded to type JSON_STRING with value 'Bye'
Case 1: '"Hello" and "Bye".' is encoded to type JSON_STRING with value '"Hello" and "Bye".'
Case 2: '"\"Hello\" and \"Bye\""' is encoded to type JSON_STRING with value '"Hello" and "Bye"'
Maestro Linden
See this note in https://wiki.secondlife.com/wiki/Json_usage_in_LSL#Type_Conversions about String values:
> LSL strings which both begin and end with
\"
are interpreted literally as JSON strings, while those without are parsed when converted into JSON.The original broken string (case 0) is following this code path, but is terminated midway with an improperly-escaped
\"
in the middle of the string. This apparently causes a parsing error, so that the resulting JSON_STRING element is only contains the text between the last two \"
in the input string.Case 1 also doesn't have json-string-style escaping of the
\"
, but it doesn't need to as the trailing .
means that llList2Json converts the string to a json string.Case 2 supplies a correctly-encoded json string, and is parsed properly - the same as Case 1, but without the trailing
.
.That said, I'm not convinced that the result achieved in case 0 as expected. Rather than the parser storing the invalid json string as 'Bye' (bounds determined by the 2 last
\"
in the string), perhaps it would be better to store that element as JSON_INVALID
since the input is not a valid json string.