You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2012/12/20 19:34:33 UTC
svn commit: r1424622 - in /incubator/mesos/trunk: src/tests/stout_tests.cpp
third_party/libprocess/include/process/http.hpp
third_party/libprocess/include/stout/json.hpp
third_party/libprocess/src/tests.cpp
Author: benh
Date: Thu Dec 20 18:34:33 2012
New Revision: 1424622
URL: http://svn.apache.org/viewvc?rev=1424622&view=rev
Log:
Added ASCII escaping for binary data in JSON strings.
From: Ben Mahler <be...@gmail.com>
Review: https://reviews.apache.org/r/8056
Modified:
incubator/mesos/trunk/src/tests/stout_tests.cpp
incubator/mesos/trunk/third_party/libprocess/include/process/http.hpp
incubator/mesos/trunk/third_party/libprocess/include/stout/json.hpp
incubator/mesos/trunk/third_party/libprocess/src/tests.cpp
Modified: incubator/mesos/trunk/src/tests/stout_tests.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/stout_tests.cpp?rev=1424622&r1=1424621&r2=1424622&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/stout_tests.cpp (original)
+++ incubator/mesos/trunk/src/tests/stout_tests.cpp Thu Dec 20 18:34:33 2012
@@ -627,6 +627,15 @@ TEST(StoutMultihashmapTest, Foreach)
}
+TEST(StoutJsonTest, BinaryData)
+{
+ JSON::String s(string("\"\\/\b\f\n\r\t\x00\x19 !#[]\x7F\xFF", 17));
+
+ EXPECT_EQ("\"\\\"\\\\\\/\\b\\f\\n\\r\\t\\u0000\\u0019 !#[]\\u007F\\u00FF\"",
+ stringify(s));
+}
+
+
#ifdef HAVE_LIBZ
TEST(StoutCompressionTest, Gzip)
{
Modified: incubator/mesos/trunk/third_party/libprocess/include/process/http.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/process/http.hpp?rev=1424622&r1=1424621&r2=1424622&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/process/http.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/process/http.hpp Thu Dec 20 18:34:33 2012
@@ -264,12 +264,16 @@ inline std::string encode(const std::str
case '[':
case ']':
case '`':
- out << '%' << std::setfill('0') << std::setw(2) << std::hex << c;
+ // NOTE: The cast to unsigned int is needed.
+ out << '%' << std::setfill('0') << std::setw(2) << std::hex
+ << std::uppercase << (unsigned int) c;
break;
default:
// ASCII control characters and non-ASCII characters.
+ // NOTE: The cast to unsigned int is needed.
if (c < 0x20 || c > 0x7F) {
- out << '%' << std::setfill('0') << std::setw(2) << std::hex << c;
+ out << '%' << std::setfill('0') << std::setw(2) << std::hex
+ << std::uppercase << (unsigned int) c;
} else {
out << c;
}
Modified: incubator/mesos/trunk/third_party/libprocess/include/stout/json.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/stout/json.hpp?rev=1424622&r1=1424621&r2=1424622&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/stout/json.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/stout/json.hpp Thu Dec 20 18:34:33 2012
@@ -1,6 +1,7 @@
#ifndef __STOUT_JSON__
#define __STOUT_JSON__
+#include <iomanip>
#include <iostream>
#include <list>
#include <map>
@@ -8,6 +9,8 @@
#include <boost/variant.hpp>
+#include <stout/foreach.hpp>
+
// TODO(jsirois): Implement parsing that constructs JSON objects.
@@ -93,22 +96,36 @@ struct Renderer : boost::static_visitor<
void operator () (const String& string) const
{
- // TODO(benh): This escaping DOES NOT handle unicode.
+ // TODO(benh): This escaping DOES NOT handle unicode, it encodes as ASCII.
+ // See RFC4627 for the JSON string specificiation.
out << "\"";
- std::string::const_iterator iterator = string.value.begin();
- while (iterator != string.value.end()) {
- switch (*iterator) {
- case '"': out << "\\\""; break;
+ foreach (unsigned char c, string.value) {
+ switch (c) {
+ case '"': out << "\\\""; break;
case '\\': out << "\\\\"; break;
- case '/': out << "\\/"; break;
- case '\b': out << "\\b"; break;
- case '\f': out << "\\f"; break;
- case '\n': out << "\\n"; break;
- case '\r': out << "\\r"; break;
- case '\t': out << "\\t"; break;
- default: out << *iterator; break;
+ case '/': out << "\\/"; break;
+ case '\b': out << "\\b"; break;
+ case '\f': out << "\\f"; break;
+ case '\n': out << "\\n"; break;
+ case '\r': out << "\\r"; break;
+ case '\t': out << "\\t"; break;
+ default:
+ // See RFC4627 for these ranges.
+ if ((c >= 0x20 && c <= 0x21) ||
+ (c >= 0x23 && c <= 0x5B) ||
+ (c >= 0x5D && c < 0x7F)) {
+ out << c;
+ } else {
+ // NOTE: We also escape all bytes > 0x7F since they imply more than
+ // 1 byte in UTF-8. This is why we don't escape UTF-8 properly.
+ // See RFC4627 for the escaping format: \uXXXX (X is a hex digit).
+ // Each byte here will be of the form: \u00XX (this is why we need
+ // setw and the cast to unsigned int).
+ out << "\\u" << std::setfill('0') << std::setw(4)
+ << std::hex << std::uppercase << (unsigned int) c;
+ }
+ break;
}
- ++iterator;
}
out << "\"";
}
Modified: incubator/mesos/trunk/third_party/libprocess/src/tests.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/src/tests.cpp?rev=1424622&r1=1424621&r2=1424622&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/src/tests.cpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/src/tests.cpp Thu Dec 20 18:34:33 2012
@@ -1333,10 +1333,11 @@ TEST(Process, async)
TEST(HTTP, encode)
{
- std::string unencoded = "a$&+,/:;=?@ \"<>#%{}|\\^~[]`\x19\x80\xFF\x00";
+ std::string unencoded = "a$&+,/:;=?@ \"<>#%{}|\\^~[]`\x19\x80\xFF";
+ unencoded += std::string("\x00", 1); // Add a null byte to the end.
std::string encoded = http::encode(unencoded);
- EXPECT_EQ("a%24%26%2B%2C%2F%3A$3B%3D%3F%40%20%22%3C%3E%32"
+ EXPECT_EQ("a%24%26%2B%2C%2F%3A%3B%3D%3F%40%20%22%3C%3E%23"
"%25%7B%7D%7C%5C%5E%7E%5B%5D%60%19%80%FF%00",
encoded);