Skip to content

dump's parameter "ensure_ascii" creates too long sequences #656

Closed

Description

@nlohmann

I detected a problem in the code of PR #654:

The code seems to created too long \uxxxx sequences. Take the € sign for instance. It is U+20AC and should be encoded as string "\u20ac". The current code encodes it as "\u00e2\u0082\u00ac". This is incorrect, as this does not roundtrip.

Example:

#include <iostream>
#include <fstream>
#include "json.hpp"

using json = nlohmann::json;

int main() {
    json j1 = u8"€";
    std::cout << j1.dump(0, ' ', false) << std::endl;
    std::cout << j1.dump(0, ' ', true) << std::endl;
    
    json j2 = json::parse("\"\\u20ac\"");
    std::cout << j2.dump(0, ' ', false) << std::endl;
    std::cout << j2.dump(0, ' ', true) << std::endl;
    
    json j3 = json::parse(j1.dump(0, ' ', true));
    std::cout << j3.dump(0, ' ', false) << std::endl;
    std::cout << j3.dump(0, ' ', true) << std::endl;
}

Output:

"€"
"\u00e2\u0082\u00ac"
"€"
"\u00e2\u0082\u00ac"
"�"
"\u00c3\u00a2\u00c2\u0082\u00c2\u00ac"

Expected output:

"€"
"\u20ac"
"€"
"\u20ac"
"€"
"\u20ac"

Sorry for not detecting this earlier. The provided test case was correct as it coped with Emojis which created longer sequences anyway.

Activity

  1. nlohmann commented on Jul 12, 2017

    @nlohmann
    OwnerAuthor

    Example in Python:

    import json
    print json.dumps('€')

    Output:

    "\u20ac"
    
  2. nlohmann commented on Jul 12, 2017

    @nlohmann
    OwnerAuthor

    We basically need a conversion from UTF-8 encoded chars to the Unicode codepoint and then use the existing escaping if the codepoint is 0..127 and UTF-16 hex(es) otherwise.

  3. ryanjmulder commented on Jul 12, 2017

    @ryanjmulder
    Contributor

    yup, I agree. Sorry about the bug, my mistake.

  4. nlohmann commented on Jul 12, 2017

    @nlohmann
    OwnerAuthor

    No worries. I used the all_unicode.json file, created a serialization in Python with the ensure_ascii parameter and compared the output with the library's dump output.

    Any help appreciated - I'm going to bed now ;)

  5. self-assigned this
    on Jul 16, 2017
  6. added a commit that references this issue on Jul 17, 2017
  7. added this to the Release 3.0.0 milestone on Jul 17, 2017
  8. nlohmann commented on Jul 17, 2017

    @nlohmann
    OwnerAuthor

    I rewrote the escaping code. @ryanjmulder - if you can find the time, I would be happy if you could have a look at the diff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions