Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

[BUG-6284] Inconsistent handling of numbers in llList2Json #14157

Closed
sl-service-account opened this issue Jun 6, 2014 · 4 comments
Closed

[BUG-6284] Inconsistent handling of numbers in llList2Json #14157

sl-service-account opened this issue Jun 6, 2014 · 4 comments

Comments

@sl-service-account
Copy link

Steps to Reproduce

Create the following script:

default
{
    state_entry()
    {
        string json = "[]";
        json = llJsonSetValue(json, [0], "\"\\\"string\\\"\"");
        json = llJsonSetValue(json, [1], "[1,3.14,1.2E+38]");
        json = llJsonSetValue(json, [2], "{\"a\":1}");
        json = llJsonSetValue(json, [3], "true");
        json = llJsonSetValue(json, [4], "false");
        json = llJsonSetValue(json, [5], "null");
        json = llJsonSetValue(json, [6], "1");
        llOwnerSay("llJsonSetValue: " + json);
        llOwnerSay("llList2Json: " + llList2Json(JSON_ARRAY,
            ["\"\\\"string\\\"\"", "[1,3.14,1.2E+38]", "{\"a\":1}", "true", "false", "null", "1"]
            ));
    }
}

Actual Behavior

The output is:

[16:41:56] Object: llJsonSetValue: ["\"string\"",[1,3.14,1.2E+38],{"a":1},true,false,null,1]
[16:41:56] Object: llList2Json: ["\"string\"",[1,3.14,1.2E+38],{"a":1},true,false,null,"1"]

Note the last "1" with quotes.

Expected Behavior

In the documentation http://wiki.secondlife.com/wiki/Json_usage_in_LSL in the bullet point String, the last sentence reads:

"LSL strings which both begin and end with """ are interpreted literally as JSON strings, while those without are parsed when converted into JSON."

Therefore it's expected for the result to be the same in both cases, namely without quotes around the number that gets passed as a string.

Original Jira Fields
Field Value
Issue BUG-6284
Summary Inconsistent handling of numbers in llList2Json
Type Bug
Priority Unset
Status Closed
Resolution Expected Behavior
Reporter Sei Lisa (sei.lisa)
Created at 2014-06-06T23:49:22Z
Updated at 2014-06-09T18:33:04Z
{
  'Business Unit': ['Platform'],
  'Date of First Response': '2014-06-06T19:36:20.319-0500',
  'System': 'SL Simulator',
  'Target Viewer Version': 'viewer-development',
  'What just happened?': 'The output is:\r\n\r\n[16:41:56] Object: llJsonSetValue: ["\\"string\\"",[1,3.14,1.2E+38],{"a":1},true,false,null,1]\r\n[16:41:56] Object: llList2Json: ["\\"string\\"",[1,3.14,1.2E+38],{"a":1},true,false,null,"1"]\r\n\r\nNote the last "1" with quotes.',
  'What were you doing when it happened?': 'Create the following script:\r\n\r\n{code}\r\ndefault\r\n{\r\n    state_entry()\r\n    {\r\n        string json = "[]";\r\n        json = llJsonSetValue(json, [0], "\\"\\\\\\"string\\\\\\"\\"");\r\n        json = llJsonSetValue(json, [1], "[1,3.14,1.2E+38]");\r\n        json = llJsonSetValue(json, [2], "{\\"a\\":1}");\r\n        json = llJsonSetValue(json, [3], "true");\r\n        json = llJsonSetValue(json, [4], "false");\r\n        json = llJsonSetValue(json, [5], "null");\r\n        json = llJsonSetValue(json, [6], "1");\r\n        llOwnerSay("llJsonSetValue: " + json);\r\n        llOwnerSay("llList2Json: " + llList2Json(JSON_ARRAY,\r\n            ["\\"\\\\\\"string\\\\\\"\\"", "[1,3.14,1.2E+38]", "{\\"a\\":1}", "true", "false", "null", "1"]\r\n            ));\r\n    }\r\n}\r\n{code}\r\n',
  'What were you expecting to happen instead?': 'In the documentation http://wiki.secondlife.com/wiki/Json_usage_in_LSL in the bullet point *String*, the last sentence reads:\r\n\r\n"LSL strings which both begin and end with "\\"" are interpreted literally as JSON strings, while those without are parsed when converted into JSON."\r\n\r\nTherefore it\'s expected for the result to be the same in both cases, namely without quotes around the number that gets passed as a string.\r\n',
  'Where': 'Everywhere',
}
@sl-service-account
Copy link
Author

Maestro Linden commented at 2014-06-07T00:36:20Z

Hi Sei, can you please elaborate on the behavior you expect for those two output lines? Is it that llJsonSetValue("",[0],"1") should return the same output as llList2Json(JSON_ARRAY, ["1"]) (i.e. that llJsonSetValue() should not have type inference for numbers), or something else?

The sentence preceding the one that you quote hints at a key difference between how llList2Json and llJsonSetValue interpret input - llList2Json() takes LSL datatypes in the input 'values' list (which may be LSL strings, integers, etc.), whereas llJsonSetValue() takes json strings as input for 'value'.

@sl-service-account
Copy link
Author

Sei Lisa commented at 2014-06-07T00:48:22Z

Yes, I expect llList2Json(JSON_ARRAY, ["1"]) to return [1], not ["1"], given that per the documentation, strings are parsed when not quoted, and parsing a JSON number results in a JSON number (just like parsing 'null' results in 'null'). Otherwise it's inconsistent with the behavior with respect to e.g. llList2Json(JSON_ARRAY, ["false"]) which results in [false], and also with the behavior of llJsonSetValue.

@sl-service-account
Copy link
Author

Sei Lisa commented at 2014-06-07T00:56:18Z

Another example: llJsonSetValue("[]", [0], "2e3") produces [2e3], but llJsonSetValue("[]", [0], "2e3a") produces ["2e3a"]. Yet llList2Json(JSON_ARRAY, ["2e3", "2e3a"]) produces ["2e3", "2e3a"].

My point is that the fact that LSL types exist that correspond to the JSON number type should not alter the behavior when passing an unquoted string.

@sl-service-account
Copy link
Author

Maestro Linden commented at 2014-06-09T18:32:28Z, updated at 2014-06-09T18:32:58Z

No, type inference is expected for llList2Json(). This script illustrates the behavior for various types:

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 = ["true", "false", "null", 1, PI, llGetKey(), "foo",
            ZERO_VECTOR, ZERO_ROTATION, "[\"inside json array\"]", "{\"jsonKey\":\"jsonValue\"}"];
        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(llList2String(input, i) + " is encoded to type " +
                decodeType(llJsonValueType(json, [i])));
        }        
    }
}

The output is:

[11:23] Object: input list: true, false, null, 1, 3.141593, b9228ab8-06e6-c7be-2093-3c786d913a9b, foo, <0.000000, 0.000000, 0.000000>, <0.000000, 0.000000, 0.000000, 1.000000>, ["inside json array"], {"jsonKey":"jsonValue"}
[11:23] Object: output json: [true,false,null,1,3.141593,"b9228ab8-06e6-c7be-2093-3c786d913a9b","foo","<0.000000, 0.000000, 0.000000>","<0.000000, 0.000000, 0.000000, 1.000000>",["inside json array"],{"jsonKey":"jsonValue"}]
[11:23] Object: true is encoded to type JSON_TRUE
[11:23] Object: false is encoded to type JSON_FALSE
[11:23] Object: null is encoded to type JSON_NULL
[11:23] Object: 1 is encoded to type JSON_NUMBER
[11:23] Object: 3.141593 is encoded to type JSON_NUMBER
[11:23] Object: b9228ab8-06e6-c7be-2093-3c786d913a9b is encoded to type JSON_STRING
[11:23] Object: foo is encoded to type JSON_STRING
[11:23] Object: <0.000000, 0.000000, 0.000000> is encoded to type JSON_STRING
[11:23] Object: <0.000000, 0.000000, 0.000000, 1.000000> is encoded to type JSON_STRING
[11:23] Object: ["inside json array"] is encoded to type JSON_ARRAY
[11:23] Object: {"jsonKey":"jsonValue"} is encoded to type JSON_OBJECT

I've added a point in the wiki to make this behavior prominent in the specification:
https://wiki.secondlife.com/w/index.php?title=LlList2Json&diff=1191180&oldid=1191140

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant