简体   繁体   中英

JavaScript failing to receive JSON from C when uint32 is a multiple of 256 plus 10?

I posted this question yesterday but edited the title and content a bit since learning a bit more through helpful comments and to make it more clear.

I've been using the following code in C to pass JSON strings from C to a Firefox extension via the native-messaging API; and it's been working well for a few months now as have been adding more code to both programs.

The variable response is a pointer to the JSON string built in C. As you can see, prefixed to the string is a unint32 indicating the number of bytes in the string.

For some reason, JSON strings of byte length equal to a multiple of 256 plus 10 appear to be successfully passed from C to the extension but are ignored by the extension. I've tried 266 and 522.

Usually, if a bad string is passed, the background script throws an error message concerning malformed JSON or a size limit violation and closes the C program; but does nothing for these size JSON strings. No errors are thrown and the C program is not closed.

Furthermore, I can run the exact same JSON strings at the command line in the C executable, and the correct JSON is printed to the screen/stdout. And, if I add/remove a byte from the strings, then the extension receives and parses them as it does the other sizes.

I write the JSON to a file on the local disk also in order to help in debugging errors and it looks fine, except for one difference that I've noticed. These strings have a smiley face in the uint32 size and after the smiley face, the remaining bytes and JSON are moved to the next line. All the other strings are on the same line as the non-typeable character.

Do you have any idea why the extension would not pick up the string?

Thank you.

int send_response( const char *response )
  {
    int rc;
    FILE *fp_out;
    fp_out = fopen( "test.txt", "w" );

    // Write response ( JSON prefixed with its UTF-8 length ).
    const uint32_t len = strlen( response );

    if ( ( rc = fwrite( &len, sizeof len, 1, fp_out ) ) != 1 ||
         ( rc = fwrite( response, len, 1, fp_out ) ) != 1 )
    {}

    if ( ( rc = fwrite( &len, sizeof len, 1, stdout ) ) != 1 ||
         ( rc = fwrite( response, sizeof *response, len, stdout ) ) != len )
      {
        perror( "fwrite" );
        return EXIT_FAILURE;
      }

    fclose( fp_out );
    return 0;

  } // close send_response

This issue is due to Windows OS regarding its use of /r/n instead of /n for new line characters. This Chrome Developer link on native messaging, the last bullet, explains a bit and links to a Windows page that describes how to use _setmode() to set stdout to _O_BINARY in the C code.

All that was required, was result = _setmode( _fileno( stdout ), _O_BINARY ); . It returns -1 if not successful.

Also, this SQLite forum response explains the cause in a little more detail.

The only reason I'm posting this as an answer rather than just adding it as additional information to my original question is that the last time I did that, somebody edited my question, removed the added information, and then closed the question. They'll probably remove this paragraph, at least, also.

Thanks to @user3386109 for pointing me in the right direction or I wouldn't have even known where to look for an answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM