Commit 320245e0d1b4be709abe98a2aa7ed1e4b9054af8

Authored by m-holger
1 parent cee746fc

In JSONParser::getToken decode escaped chars inside state ls_backslash

(except '\\' and '\uXXXX')
Showing 1 changed file with 31 additions and 6 deletions
libqpdf/JSON.cc
... ... @@ -790,7 +790,6 @@ JSONParser::decode_string(std::string const& str, qpdf_offset_t offset)
790 790 i += 4;
791 791 break;
792 792 default:
793   - throw std::logic_error("JSON parse: bad character after \\");
794 793 break;
795 794 }
796 795 } else {
... ... @@ -1052,17 +1051,43 @@ JSONParser::getToken()
1052 1051 ready = true;
1053 1052 } else if (*p == '\\') {
1054 1053 lex_state = ls_backslash;
  1054 + action = ignore;
1055 1055 }
1056 1056 break;
1057 1057  
1058 1058 case ls_backslash:
1059   - /* cSpell: ignore bfnrt */
1060   - if (strchr("\\\"/bfnrt", *p)) {
1061   - lex_state = ls_string;
1062   - } else if (*p == 'u') {
  1059 + action = ignore;
  1060 + lex_state = ls_string;
  1061 + switch (*p) {
  1062 + case '\\':
  1063 + token += "\\\\";
  1064 + case '\"':
  1065 + case '/':
  1066 + // \/ is allowed in json input, but so is /, so we
  1067 + // don't map / to \/ in output.
  1068 + token += *p;
  1069 + break;
  1070 + case 'b':
  1071 + token += '\b';
  1072 + break;
  1073 + case 'f':
  1074 + token += '\f';
  1075 + break;
  1076 + case 'n':
  1077 + token += '\n';
  1078 + break;
  1079 + case 'r':
  1080 + token += '\r';
  1081 + break;
  1082 + case 't':
  1083 + token += '\t';
  1084 + break;
  1085 + case 'u':
  1086 + token += "\\u";
1063 1087 lex_state = ls_u4;
1064 1088 u_count = 0;
1065   - } else {
  1089 + break;
  1090 + default:
1066 1091 QTC::TC("libtests", "JSON parse backslash bad character");
1067 1092 throw std::runtime_error(
1068 1093 "JSON: offset " + std::to_string(offset) +
... ...