Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"1," produces an object with int 1; "1" produces a null object #690

Closed
agroce opened this issue Dec 24, 2020 · 4 comments
Closed

"1," produces an object with int 1; "1" produces a null object #690

agroce opened this issue Dec 24, 2020 · 4 comments

Comments

@agroce
Copy link

agroce commented Dec 24, 2020

Describe the bug

Not sure if this is a bug or just me mis-using the API, but fuzzing with DeepState via https://github.com/agroce/deepstate-json-c gives me a behavior that I don't think makes sense:

#include <iostream>
using namespace std;

#include <assert.h>
#include <string.h>
#include <json.h>

int main () {
  size_t size1 = 2;
  const char* str1 = "1,";
  cout << "String 1:" << str1 << endl;
  cout << "Length 1:" << size1 << endl;
  json_tokener *tok1 = json_tokener_new();
  json_object *obj1 = json_tokener_parse_ex(tok1, str1, size1);
  cout << "Type 1:" << json_object_get_type(obj1) << endl;
  if (obj1 != NULL) {
    const char* str2 = json_object_to_json_string(obj1);
    size_t size2 = strlen(str2);;
    cout << "String 2:" << str2 << endl;
    cout << "Length 2:" << size2 << endl;
    json_tokener *tok2 = json_tokener_new();    
    json_object *obj2 = json_tokener_parse_ex(tok2, str2, size2);
    assert(obj2 != NULL);
    cout << "Type 2:" << json_object_get_type(obj2) << endl;
    assert(json_object_equal(obj1, obj2));
    json_object_put(obj2);
    json_tokener_free(tok2);
  }
  json_object_put(obj1);
  json_tokener_free(tok1);
}

produces:

~/json-c-build$ ./Bug1
String 1:1,
Length 1:2
Type 1:3
String 2:1
Length 2:1
Bug1: Bug1.cpp:23: int main(): Assertion `obj2 != NULL' failed.

In other words, "1," turns into a JSON object containing the int 1. "1" turns into a null object.

Steps To Reproduce

See the above small C++ code, based on the fuzzing harness.

Version and Platform

  • json-c version: 1fcb9e4
  • OS: Ubuntu 18.04
  • No odd flags
@ploxiln
Copy link
Contributor

ploxiln commented Dec 25, 2020

It doesn't know if there are more digits after the "1" or not, so it has not finished that object.

see also #681 (comment)

@agroce
Copy link
Author

agroce commented Dec 25, 2020

Adding whitespace at the end of the string for obj2 would presumably force it to round-trip properly?

@hawicz
Copy link
Member

hawicz commented Dec 28, 2020

Adding whitespace would work, but a more natural way to do it would be to include the final nul byte in the length that you pass to json_tokener_parse_ex(). i.e. size_t size2 = strlen(str2) + 1;

@hawicz hawicz closed this as completed Dec 28, 2020
@agroce
Copy link
Author

agroce commented Dec 28, 2020

Oh, I see -- that makes a lot of sense! Due to "e" and float vs int interpretations the round-trip still doesn't quite work, but I think that can be dealt with.

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

No branches or pull requests

3 participants