| 4362 | } |
| 4363 | |
| 4364 | static String valueToQuotedStringN(const char* value, size_t length, |
| 4365 | bool emitUTF8 = false) { |
| 4366 | if (value == nullptr) |
| 4367 | return ""; |
| 4368 | |
| 4369 | if (!doesAnyCharRequireEscaping(value, length)) |
| 4370 | return String("\"") + value + "\""; |
| 4371 | // We have to walk value and escape any special characters. |
| 4372 | // Appending to String is not efficient, but this should be rare. |
| 4373 | // (Note: forward slashes are *not* rare, but I am not escaping them.) |
| 4374 | String::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL |
| 4375 | String result; |
| 4376 | result.reserve(maxsize); // to avoid lots of mallocs |
| 4377 | result += "\""; |
| 4378 | char const* end = value + length; |
| 4379 | for (const char* c = value; c != end; ++c) { |
| 4380 | switch (*c) { |
| 4381 | case '\"': |
| 4382 | result += "\\\""; |
| 4383 | break; |
| 4384 | case '\\': |
| 4385 | result += "\\\\"; |
| 4386 | break; |
| 4387 | case '\b': |
| 4388 | result += "\\b"; |
| 4389 | break; |
| 4390 | case '\f': |
| 4391 | result += "\\f"; |
| 4392 | break; |
| 4393 | case '\n': |
| 4394 | result += "\\n"; |
| 4395 | break; |
| 4396 | case '\r': |
| 4397 | result += "\\r"; |
| 4398 | break; |
| 4399 | case '\t': |
| 4400 | result += "\\t"; |
| 4401 | break; |
| 4402 | // case '/': |
| 4403 | // Even though \/ is considered a legal escape in JSON, a bare |
| 4404 | // slash is also legal, so I see no reason to escape it. |
| 4405 | // (I hope I am not misunderstanding something.) |
| 4406 | // blep notes: actually escaping \/ may be useful in javascript to avoid </ |
| 4407 | // sequence. |
| 4408 | // Should add a flag to allow this compatibility mode and prevent this |
| 4409 | // sequence from occurring. |
| 4410 | default: { |
| 4411 | if (emitUTF8) { |
| 4412 | unsigned codepoint = static_cast<unsigned char>(*c); |
| 4413 | if (codepoint < 0x20) { |
| 4414 | appendHex(result, codepoint); |
| 4415 | } else { |
| 4416 | appendRaw(result, codepoint); |
| 4417 | } |
| 4418 | } else { |
| 4419 | unsigned codepoint = utf8ToCodepoint(c, end); // modifies `c` |
| 4420 | if (codepoint < 0x20) { |
| 4421 | appendHex(result, codepoint); |
no test coverage detected