0
0
mirror of https://github.com/PostHog/posthog.git synced 2024-11-22 08:40:03 +01:00
posthog/hogql_parser/string.cpp
Michael Matloka 8f62e85c9d
chore(hogql): Full error & NULL handling in C++ parser (1.0.0) (#18240)
* chore(hogql): Be defensive against NULLs in the C++ parser

* Clean up on C++ exceptions

* Add to CONTRIBUTING guide

* Revert `AllowShortFunctionsOnASingleLine` change

* Update HogQLX additions too

* Bump version to 1.0.0

* Use new hogql-parser version

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
2023-10-27 13:37:15 +02:00

59 lines
2.1 KiB
C++

#include <boost/algorithm/string.hpp>
#include "error.h"
#include "string.h"
using namespace std;
string unquote_string(string text) {
size_t original_text_size = text.size();
if (original_text_size == 0) {
throw ParsingException("Encountered an unexpected empty string input");
}
const char first_char = text.front();
const char last_char = text.back();
if (first_char == '\'' && last_char == '\'') {
text = text.substr(1, original_text_size - 2);
boost::replace_all(text, "''", "'");
boost::replace_all(text, "\\'", "'");
} else if (first_char == '"' && last_char == '"') {
text = text.substr(1, original_text_size - 2);
boost::replace_all(text, "\"\"", "\"");
boost::replace_all(text, "\\\"", "\"");
} else if (first_char == '`' && last_char == '`') {
text = text.substr(1, original_text_size - 2);
boost::replace_all(text, "``", "`");
boost::replace_all(text, "\\`", "`");
} else if (first_char == '{' && last_char == '}') {
text = text.substr(1, original_text_size - 2);
boost::replace_all(text, "{{", "{");
boost::replace_all(text, "\\{", "{");
} else {
throw SyntaxException("Invalid string literal, must start and end with the same quote type: " + text);
}
// Copied from clickhouse_driver/util/escape.py
boost::replace_all(text, "\\a", "\a");
boost::replace_all(text, "\\b", "\b");
boost::replace_all(text, "\\f", "\f");
boost::replace_all(text, "\\n", "\n");
boost::replace_all(text, "\\r", "\r");
boost::replace_all(text, "\\t", "\t");
boost::replace_all(text, "\\v", "\v");
boost::replace_all(text, "\\0", ""); // NUL characters are ignored
boost::replace_all(text, "\\\\", "\\");
return text;
}
string unquote_string_terminal(antlr4::tree::TerminalNode* node) {
string text = node->getText();
try {
return unquote_string(text);
} catch (SyntaxException& e) {
throw SyntaxException(e.what(), node->getSymbol()->getStartIndex(), node->getSymbol()->getStopIndex() + 1);
} catch (ParsingException& e) {
throw ParsingException(e.what(), node->getSymbol()->getStartIndex(), node->getSymbol()->getStopIndex() + 1);
}
}