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

Poco::JSON::Stringifier::stringify bad behaviour #482

Closed
miguelangelorenes opened this issue Jul 3, 2014 · 8 comments
Closed

Poco::JSON::Stringifier::stringify bad behaviour #482

miguelangelorenes opened this issue Jul 3, 2014 · 8 comments
Assignees
Milestone

Comments

@miguelangelorenes
Copy link

Testing this code
std::string str = "HTTP/1.1 200 OK\r\nDate: Thu, 03 Jul 2014 12:57:06 GMT\r\nConnection: Close";
Poco::JSON::Object obj;
obj.set("payload", str);
std::ostringstream oss;
Poco::JSON::Stringifier::stringify( obj, oss );
std::cout << "Payload before Stringify: " << str << std::endl;
std::cout << "Payload after Stringify: " << oss.str() << std::endl;

I am getting the next output:
Payload before Stringify: HTTP/1.1 200 OK
Date: Thu, 03 Jul 2014 12:57:06 GMT
Connection: Close
\ayload after Stringify: {"payload":"HTTP/1.1 200 OK
\ate: Thu, 03 Jul 2014 12:57:06 GMT
Connection: Close"}

With poco master version, previous #176 fix, this code worked fine.

Taking a look on Poco::JSON::Stringifier::formatString code, it looks like:
if (*it <= 0x1F || *it == '"' || *it == '' || *it == '/')
{
out << '';
}
out << *it;
is not working ok because is transforming, for example, "\n" to "\n".

As additional information, I changed new "formatString" code the previous implementation and it worked fine.

The same problem happens on Poco-develop version.

@kolbma
Copy link
Contributor

kolbma commented Jul 9, 2014

What is your problem?
When newlines got stringified, they are escaped. That is IMO correct.
What is your intention? The HTTP header stuff in combination with an JSON object looks strange.

@miguelangelorenes
Copy link
Author

It could be strange but It is not really incorrect. Maybe HTTP headers dont let you see the problem: I am sending plain text(like HTTP) with some "\r\n" as a payload in a JSON and receiver part is getting different data.

Maybe I am breaking some rule about JSON and is better if I convert it to Base64 before send my data, anyway as I said: I found this problem after #176 fix.

@kolbma
Copy link
Contributor

kolbma commented Jul 10, 2014

Ah. I've compile your code and see now that the output is really so wrong. First I've thought that this has something to do with securing the GitHub input data ;-)
Now I understand your problem. But it is ok that \r/\n would become stringified/escaped \\r/\\n.
But there must be some control chars in the stringified data, because the output is wrong before the const char* "Payload".
So this is a bug.

@kolbma
Copy link
Contributor

kolbma commented Jul 10, 2014

For me it looks like the stringify makes...
\n ==> \\\n
\r ==> \\\r
Then the output is a \ plus the control char \n / \r!

This test confirms that ...

#include <string>
#include <iostream>
#include <sstream>
#include <cassert>
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Stringifier.h"

int main() {
    std::string str = "\r";
    std::string str2 = "\n";
    Poco::JSON::Object obj, obj2;
    obj.set("payload", str);
    obj2.set("payload", str2);
    std::ostringstream oss, oss2;
    Poco::JSON::Stringifier::stringify(obj, oss);
    Poco::JSON::Stringifier::stringify(obj2, oss2);
    assert(oss.str() != "{\"payload\":\"\\\r\"}");
    assert(oss.str() == "{\"payload\":\"\\r\"}");
    std::cout << "\"" << oss.str() << "\"" << std::endl;
    assert(oss2.str() != "{\"payload\":\"\\\n\"}");
    assert(oss2.str() == "{\"payload\":\"\\n\"}");
    std::cout << "\"" << oss2.str() << "\"" << std::endl;
}

Output:
main2.cpp:18: int main(): Assertion 'oss.str() != "{\"payload\":\"\\\r\"}"' failed.

@miguelangelorenes
Copy link
Author

My apologies, I forgot to see the preview before publish my comment. Yes, I wanted to write in the post that the problem was convert "\n" to "\\n" but it was showing bad and for that I decided to go back the previous formatString version because it worked ok.

Thanks.

@gooddayzy
Copy link

I think there is still a problem in stringify.

Similar to "HTTP/1.1 200 OK" => "HTTP/1.1 200 OK", which is mentioned above,

I got "......ZGWuuD3/A4......" => "......ZGWuuD3/A4......", where a '' is added before the '/'.

I'm using 1.6.1.

Thanks.

@aleks-f
Copy link
Member

aleks-f commented Aug 25, 2015

There is no problem. According to RFC7159 "Any character may be escaped."

char = unescaped /
          escape (
              %x22 /          ; "    quotation mark  U+0022
              %x5C /          ; \    reverse solidus U+005C
              %x2F /          ; /    solidus         U+002F
              %x62 /          ; b    backspace       U+0008
              %x66 /          ; f    form feed       U+000C
              %x6E /          ; n    line feed       U+000A
              %x72 /          ; r    carriage return U+000D
              %x74 /          ; t    tab             U+0009
              %x75 4HEXDIG )  ; uXXXX                U+XXXX

Escaping slash helps when embedding JSON in <script> tags, which otherwise do not allow it.

@aarruunn-23
Copy link

aarruunn-23 commented Aug 22, 2016

The same issue of
\n ==> \n
\r ==> \r
is there in poco 1.7.4. I am using Poco::JSON::Object::Stringify method instead of Poco::JSON::Stringifier::Stringify method. Can you please resolve the issue in Object class also

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

No branches or pull requests

6 participants