Skip to content

Commit

Permalink
Squash: JSON: Support escape special chars. (#1758)
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Oct 20, 2021
1 parent 9a017f4 commit 665b5f4
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 7 deletions.
2 changes: 2 additions & 0 deletions trunk/doc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ The changelog for SRS.

## SRS 4.0 Changelog

* v4.0, 2021-10-20, Merge [#1758](https://github.com/ossrs/srs/pull/1758): JSON: Support escape special chars. v4.0.182
* v4.0, 2021-10-19, Merge [#1754](https://github.com/ossrs/srs/pull/1754): RTMP: If port is explicity set to 0, use default 1935. v4.0.181
* v4.0, 2021-10-18, Merge [#2670](https://github.com/ossrs/srs/pull/2670): SRT: Solve mpegts demux assert bug. v4.0.180
* v4.0, 2021-10-16, Merge [#2665](https://github.com/ossrs/srs/pull/2665): API: Fix the same 'client_id' error when asynchronous call. v4.0.179
* v4.0, 2021-10-13, Merge [#2671](https://github.com/ossrs/srs/pull/2671): SRT: Pes error when mpegts demux in srt. v4.0.178
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core_version4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

#define VERSION_MAJOR 4
#define VERSION_MINOR 0
#define VERSION_REVISION 180
#define VERSION_REVISION 182

#endif
28 changes: 22 additions & 6 deletions trunk/src/protocol/srs_protocol_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1538,25 +1538,41 @@ SrsJsonArray* SrsJsonAny::to_array()
return p;
}

string escape(string v)
// @see https://github.com/ossrs/srs/pull/1758/files#diff-9568479ef5cb0aa1ade2381e11e9c066c01bf9c4bbed70ffa27094d08bb27380R370
// @see https://github.com/json-parser/json-builder/blob/2d8c6671926d104c5dcd43ccd2b1431a3f0299e0/json-builder.c#L495
string json_serialize_string(const string& v)
{
stringstream ss;

for (int i = 0; i < (int)v.length(); i++) {
if (v.at(i) == '"') {
ss << '\\';
ss << "\"";

const char* start = v.data();
const char* end = start + v.length();
for (const char* p = start; p < end; ++p) {
switch (*p) {
case '"': ss << '\\' << '"'; break;
case '\\': ss << '\\' << '\\'; break;
case '\b': ss << '\\' << 'b'; break;
case '\f': ss << '\\' << 'f'; break;
case '\n': ss << '\\' << 'n'; break;
case '\r': ss << '\\' << 'r'; break;
case '\t': ss << '\\' << 't'; break;
default: ss << *p;
}
ss << v.at(i);
}

ss << "\"";

return ss.str();
}

string SrsJsonAny::dumps()
{
switch (marker) {
case SRS_JSON_String: {
return "\"" + escape(to_str()) + "\"";
SrsJsonString* p = dynamic_cast<SrsJsonString*>(this);
srs_assert(p != NULL);
return json_serialize_string(p->value);
}
case SRS_JSON_Boolean: {
return to_boolean()? "true" : "false";
Expand Down
66 changes: 66 additions & 0 deletions trunk/src/utest/srs_utest_amf0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2626,6 +2626,72 @@ VOID TEST(ProtocolJSONTest, Dumps)
}
}

VOID TEST(ProtocolJSONTest, DumpsSpecialChars)
{
if (true) {
SrsJsonAny* p = SrsJsonAny::str("hello");
EXPECT_TRUE(p->is_string());
EXPECT_STREQ("\"hello\"", p->dumps().c_str());
srs_freep(p);
}

if (true) {
SrsJsonAny* p = SrsJsonAny::str("he\"llo");
EXPECT_TRUE(p->is_string());
EXPECT_STREQ("\"he\\\"llo\"", p->dumps().c_str());
srs_freep(p);
}

if (true) {
SrsJsonAny* p = SrsJsonAny::str("he\\llo");
EXPECT_TRUE(p->is_string());
EXPECT_STREQ("\"he\\\\llo\"", p->dumps().c_str());
srs_freep(p);
}

if (true) {
SrsJsonAny* p = SrsJsonAny::str("he\nllo");
EXPECT_TRUE(p->is_string());
EXPECT_STREQ("\"he\\nllo\"", p->dumps().c_str());
srs_freep(p);
}

if (true) {
SrsJsonAny* p = SrsJsonAny::str("he\tllo");
EXPECT_TRUE(p->is_string());
EXPECT_STREQ("\"he\\tllo\"", p->dumps().c_str());
srs_freep(p);
}

if (true) {
SrsJsonAny* p = SrsJsonAny::str("he\bllo");
EXPECT_TRUE(p->is_string());
EXPECT_STREQ("\"he\\bllo\"", p->dumps().c_str());
srs_freep(p);
}

if (true) {
SrsJsonAny* p = SrsJsonAny::str("he\fllo");
EXPECT_TRUE(p->is_string());
EXPECT_STREQ("\"he\\fllo\"", p->dumps().c_str());
srs_freep(p);
}

if (true) {
SrsJsonAny* p = SrsJsonAny::str("he\rllo");
EXPECT_TRUE(p->is_string());
EXPECT_STREQ("\"he\\rllo\"", p->dumps().c_str());
srs_freep(p);
}

if (true) {
SrsJsonAny* p = SrsJsonAny::str("hello视频");
EXPECT_TRUE(p->is_string());
EXPECT_STREQ("\"hello\xE8\xA7\x86\xE9\xA2\x91\"", p->dumps().c_str());
srs_freep(p);
}
}

VOID TEST(ProtocolJSONTest, Parse)
{
if (true) {
Expand Down

0 comments on commit 665b5f4

Please sign in to comment.