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
This issue was fixed in 11.7.3 via bug number PSC00351471
For what it's worth. It doesn't crash on 11.7.3 (win x64).
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)
This issue was fixed in 11.7.3 via bug number PSC00351471
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)
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.
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.
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