JSON ObjectModelParser crashes, what am I doing wrong?

Posted by Jeroen Eeuwes on 06-Jun-2018 01:33

Hi everybody,

I'm writing a program that will receive a JSON and take some actions depending on the contents of the JSON.

One of the first steps I want to do is validate that I did actually get a JSON. So reading the docs about ObectModelParser:Parse()  at https://documentation.progress.com/output/ua/OpenEdge_latest/pdsoe/PLUGINS_ROOT/com.openedge.pdt.langref.help/rfi1424920927865.html#rfi1424920927865 and read the following lines: "The returned value is either a JsonObject or a JsonArray. If the JSON syntax is incorrect, a JsonParserError is raised."

Exactly what I want and so I implemented it. When testing it looks like the ObjectModelParser doesn't always recognises that a file isn't valid JSON and even worse it sometimes crashes the entire session.

Below some simple code to illustrate this. In test 1 it does correctly recognise the JSON is valid, in test 2, 3 and 4 it will correctly say the JSON is invalid. In test 5 and 6 it will incorrectly say the JSON is valid and with test 7 you get a crash with a protrace stating:

Exception code: C0000005 ACCESS_VIOLATION
Fault address:  0FDFB5D8 01:0066A5D8 C:\Progressx86\OpenEdge\bin\prow32.dll

As far as I can find it will always crash if the input starts with a number.

I I remove the NO-ERROR from the parse statement it will generate the errors but test 7 still crashes.

In my case the JSON should always be an object so if I test if the first character is a { I can circumvent the crash, but I'd rather not build my own JSON validator for all other possible things that could go awry.

What am I doing wrong?

I've tried this on 11.5 and 11.6 but not on 11.7.

Test code below:

USING Progress.Json.ObjectModel.*.

DEF VAR cTest AS CHARACTER NO-UNDO.

cTest = '~{"name": "value", "number": 123}'.
RUN TestJson(1, cTest).

cTest = 'abcd~{"name": "value", "number": 123}'.
RUN TestJson(2, cTest).

cTest = '~{"name": "value", abcd, "number": 123}'.
RUN TestJson(3, cTest).

cTest = '~{"name": "value", 123, "number": 123}'.
RUN TestJson(4, cTest).

cTest = '~{"name": "value", "number": 123}abcd'.
RUN TestJson(5, cTest).

cTest = '~{"name": "value", "number": 123}1234'.
RUN TestJson(6, cTest).

/* This results in a crash */
cTest = '1234~{"name": "value", "number": 123}'.
RUN TestJson(7, cTest).


PROCEDURE TestJson:
  DEFINE INPUT PARAMETER piNmbr AS INTEGER  NO-UNDO.
  DEFINE INPUT PARAMETER pcTest AS LONGCHAR NO-UNDO.

  DEF VAR oParser        AS ObjectModelParser NO-UNDO.
  DEF VAR oJsonConstruct AS JsonConstruct     NO-UNDO.
  DEF VAR lJsonOK                        AS LOGICAL           NO-UNDO.
 
  oParser = NEW ObjectModelParser().
  oJsonConstruct = oParser:Parse(cTest) NO-ERROR.

  IF VALID-OBJECT(oJsonConstruct) = FALSE
    OR oJsonConstruct = ?
    OR ERROR-STATUS:ERROR = TRUE
    OR ERROR-STATUS:NUM-MESSAGES > 0
  THEN lJsonOk = FALSE.
  ELSE lJsonOk = TRUE.

  MESSAGE "Test number: " piNmbr SKIP  
          "Is the Json OK? " lJsonOK SKIP(1)
          cTest
    VIEW-AS ALERT-BOX.
    

  CATCH errtest AS Progress.Lang.Error:
    DEF VAR iLoop AS INTEGER NO-UNDO.
    DO iLoop = 1 TO errtest:NumMessages:
              MESSAGE "Parser error" SKIP "error: " STRING(iLoop) SKIP errtest:GetMessage(iLoop) VIEW-AS ALERT-BOX.
            END.
  END CATCH.
END PROCEDURE.

Best regards, Jeroen

Posted by Robin Brown on 06-Jun-2018 08:32

This issue was fixed in 11.7.3 via bug number PSC00351471

All Replies

Posted by bronco on 06-Jun-2018 02:15

For what it's worth. It doesn't crash on 11.7.3 (win x64).

Posted by Stefan Drissen on 06-Jun-2018 02:18

And it also crashes 11.7.1 - abldojo.services.progress.com:443/

And the abldojo database is not liking the crashes :-)

You have attempted to connect to a database with too many
users connected to it. Retry the connection later,
or increase -n on the server. (5291)

Posted by Robin Brown on 06-Jun-2018 08:32

This issue was fixed in 11.7.3 via bug number PSC00351471

Posted by Torben on 06-Jun-2018 08:43

On both 32 and 64 bit version of 11.7.3 on Windows 10 it don't crash and I get following error:

Json Parser Error at offset 4: parse error: client cancelled parse via callback return value. (16068)

Posted by Robin Brown on 06-Jun-2018 11:10

All but the first test string are invalid JSON.  If you take NO-ERROR off of oParser:Parse(), you'll see all of the error messages in the CATCH block.  The error message varies depending where the JsonParser is in the process when it detects the error.

The cases where the invalid text was appended to the JSON object did not fail, and the appended text was ignored.

Posted by Jeroen Eeuwes on 08-Jun-2018 09:27

Hi Robin,

Thanks for letting me know it's solved in 11.7.3.

That means that if for some reason a right brace appears at a "valid" ending the system will be losing data.

For example, this JSON will be valid according to the parser, right?

{"invoice": "12345", "customer": "Jane Doe", "address": "Somewhere over the rainbow", "total amount": 777.77}, "amount due": 555.55}

But the system will never know the amount still due because it is discarded by the parser? That just seems wrong.

Posted by Robin Brown on 08-Jun-2018 09:51

You are correct.  This is considered valid JSON by the OpenEdge JSON parser, but it is not.  The JSON validator on https://jsonlint.com/ shows:

----------------------^

Expecting 'EOF', got ',',  shows this:

Error: Parse error on line 6:

...al amount": 777.77}, "amount due": 555.

----------------------^

Expecting 'EOF', got ','

Please log an issue with Tech Support so that we can get this fixed.

Thank you,

Robin

This thread is closed