| 468 | } |
| 469 | |
| 470 | std::string decodeEscapeSequences(const std::string& input) { |
| 471 | std::regex unicodeRegex(R"(\\u([0-9A-Fa-f]{4})|\\U([0-9A-Fa-f]{8}))"); |
| 472 | std::string result = input; |
| 473 | std::smatch match; |
| 474 | while (std::regex_search(result, match, unicodeRegex)) { |
| 475 | std::string codepointStr; |
| 476 | if (match[1].matched) { |
| 477 | codepointStr = match[1].str(); |
| 478 | } else if (match[2].matched) { |
| 479 | codepointStr = match[2].str(); |
| 480 | } |
| 481 | uint32_t codepoint = static_cast<uint32_t>(std::stoull(codepointStr, nullptr, 16)); |
| 482 | if (codepoint > 0x10FFFF) { |
| 483 | throw std::runtime_error("Invalid Unicode codepoint"); |
| 484 | } |
| 485 | if (codepoint == 0) { |
| 486 | throw std::runtime_error("Null character not allowed"); |
| 487 | } |
| 488 | // Check for surrogate pairs |
| 489 | if (0xD800 <= codepoint && codepoint <= 0xDBFF) { |
| 490 | // High surrogate, look for the next low surrogate |
| 491 | std::smatch nextMatch; |
| 492 | std::string remainingString = result.substr(match.position() + match.length()); |
| 493 | if (std::regex_search(remainingString, nextMatch, unicodeRegex)) { |
| 494 | std::string nextCodepointStr = nextMatch[1].str(); |
| 495 | int nextCodepoint = std::stoi(nextCodepointStr, nullptr, 16); |
| 496 | if (0xDC00 <= nextCodepoint && nextCodepoint <= 0xDFFF) { |
| 497 | // Valid surrogate pair |
| 498 | codepoint = 0x10000 + ((codepoint - 0xD800) << 10) + (nextCodepoint - 0xDC00); |
| 499 | result.replace(match.position() + match.length(), nextMatch.length(), ""); |
| 500 | } else { |
| 501 | throw std::runtime_error("Invalid surrogate pair"); |
| 502 | } |
| 503 | } else { |
| 504 | throw std::runtime_error("Unmatched high surrogate"); |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | // Convert codepoint to UTF-8 |
| 509 | char utf8Char[5] = {0}; // UTF-8 characters can be up to 4 bytes + null terminator |
| 510 | int size = 0; |
| 511 | if (!Utf8Proc::codepointToUtf8(codepoint, size, utf8Char)) { |
| 512 | throw std::runtime_error("Failed to convert codepoint to UTF-8"); |
| 513 | } |
| 514 | |
| 515 | // Replace the escape sequence with the actual UTF-8 character |
| 516 | result.replace(match.position(), match.length(), std::string(utf8Char, size)); |
| 517 | } |
| 518 | return result; |
| 519 | } |
| 520 | |
| 521 | void EmbeddedShell::checkConfidentialStatement(const std::string& query, QueryResult* queryResult, |
| 522 | std::string& input) { |
no test coverage detected