Skip to content

Conversation

@jasonpcarroll
Copy link
Member

@jasonpcarroll jasonpcarroll commented Dec 2, 2025

Description

This change fixes the JSON_Validate API:

  • to correctly invalidate collections (arrays/objects) with missing commas (e.g. [3[4]], or { "key1": "value1, "key2" : "value2" })
  • to correctly invalidate values with escaped control characters (e.g. "\<tab>" where <tab> is the actual character instead of t)
  • to correctly validate values with the hex escaped 0 value (i.e. \u0000 should be allowed).

Test Steps

Ran coreJSON against the y (valid) and n (invalid) JSON documents found in https://github.com/nst/JSONTestSuite/tree/master/test_parsing.

Checklist:

  • I have tested my changes. No regression in existing tests.
  • I have modified and/or added unit-tests to cover the code changes in this Pull Request.

Related Issue

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.


switch( c )
{
case '\0':
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break from the default case - no need for this.

}

if( ( i == end ) && ( value > 0U ) )
if( i == end )
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allow value of 0 (\u0000) per JSON spec.


default:

/* a control character: (NUL,SPACE) */
Copy link
Member Author

@jasonpcarroll jasonpcarroll Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is invalid... escaped literal control characters should fail validation per spec, thus I have removed it.

depth--;

if( ( skipSpaceAndComma( buf, &i, max ) == true ) &&
isOpenBracket_( stack[ depth ] ) )
Copy link
Member Author

@jasonpcarroll jasonpcarroll Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this isOpenBracket_ check as there is no point... stack[ depth ] will always contain an open bracket when depth >= 0.


if( skipSpaceAndComma( buf, &i, max ) != true )
{
/* After parsing a scalar, we must either have a comma (followed by more content)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes cases such as [3[4]] from being parsed as valid.

{
/* After closing a nested collection, if there is no comma found when calling
* skipSpaceAndComma, then we must be at the end of the parent collection. */
if( ( i < max ) && !isMatchingBracket_( stack[ depth ], buf[ i ] ) )
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes cases where missing commas between collections was considered valid. (e.g. [ { "key1" : "value1"} {"key2":"value2"}])

/* More details at: https://github.com/FreeRTOS/coreJSON/blob/main/MISRA.md#rule-143 */
/* coverity[misra_c_2012_rule_14_3_violation] */
end = ( i <= ( SIZE_MAX - HEX_ESCAPE_LENGTH ) ) ? ( i + HEX_ESCAPE_LENGTH ) : SIZE_MAX;
end = i + HEX_ESCAPE_LENGTH;
Copy link
Member Author

@jasonpcarroll jasonpcarroll Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This previous logic relied on value remaning 0 to determine whether or not a hex escape was skipped. because the value 0 is now allowed, I have updated this logic to always add HEX_ESCAPE_LENGTH to i as the end and added an overflow check.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that way the i == end logic holds for determining if a hex escape value was parsed.

uses: FreeRTOS/CI-CD-Github-Actions/complexity@main
with:
path: ./
horrid_threshold: 12
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be frank here - I did not want to spend extra time reducing the complexity :)


if( skipSpaceAndComma( buf, &i, max ) == true )
{
+ __CPROVER_assume( isOpenBracket_(stack[depth]));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have verified by code inspection that this assumption should hold for the loop - I would ask that reviewers verify this as well - see comment about redundant isOpenBracket_ check.

@jasonpcarroll jasonpcarroll merged commit 3a14ef8 into FreeRTOS:main Dec 5, 2025
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants