From 2cde63a25ced0c252ff1929be7c242c6b40e3d9f Mon Sep 17 00:00:00 2001 From: avogar Date: Mon, 3 Apr 2023 16:25:22 +0000 Subject: [PATCH] Avoid abort in protobuf library in debug build --- src/Formats/ProtobufSchemas.cpp | 31 ++++++++++++++++--- .../02705_protobuf_debug_abort.reference | 1 + .../0_stateless/02705_protobuf_debug_abort.sh | 18 +++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 tests/queries/0_stateless/02705_protobuf_debug_abort.reference create mode 100755 tests/queries/0_stateless/02705_protobuf_debug_abort.sh diff --git a/src/Formats/ProtobufSchemas.cpp b/src/Formats/ProtobufSchemas.cpp index efc0a4e694f..048d88ff2d1 100644 --- a/src/Formats/ProtobufSchemas.cpp +++ b/src/Formats/ProtobufSchemas.cpp @@ -41,8 +41,19 @@ public: return descriptor; const auto * file_descriptor = importer.Import(schema_path); - // If there are parsing errors, AddError() throws an exception and in this case the following line - // isn't executed. + if (error) + { + auto info = error.value(); + error.reset(); + throw Exception( + ErrorCodes::CANNOT_PARSE_PROTOBUF_SCHEMA, + "Cannot parse '{}' file, found an error at line {}, column {}, {}", + info.filename, + std::to_string(info.line), + std::to_string(info.column), + info.message); + } + assert(file_descriptor); if (with_envelope == WithEnvelope::No) @@ -74,14 +85,24 @@ private: // Overrides google::protobuf::compiler::MultiFileErrorCollector: void AddError(const String & filename, int line, int column, const String & message) override { - throw Exception(ErrorCodes::CANNOT_PARSE_PROTOBUF_SCHEMA, - "Cannot parse '{}' file, found an error at line {}, column {}, {}", - filename, std::to_string(line), std::to_string(column), message); + /// Protobuf library code is not exception safe, we should + /// remember error and throw in later from our side. + error = ErrorInfo{filename, line, column, message}; } google::protobuf::compiler::DiskSourceTree disk_source_tree; google::protobuf::compiler::Importer importer; const WithEnvelope with_envelope; + + struct ErrorInfo + { + String filename; + int line; + int column; + String message; + }; + + std::optional error; }; diff --git a/tests/queries/0_stateless/02705_protobuf_debug_abort.reference b/tests/queries/0_stateless/02705_protobuf_debug_abort.reference new file mode 100644 index 00000000000..d00491fd7e5 --- /dev/null +++ b/tests/queries/0_stateless/02705_protobuf_debug_abort.reference @@ -0,0 +1 @@ +1 diff --git a/tests/queries/0_stateless/02705_protobuf_debug_abort.sh b/tests/queries/0_stateless/02705_protobuf_debug_abort.sh new file mode 100755 index 00000000000..4a66cfca352 --- /dev/null +++ b/tests/queries/0_stateless/02705_protobuf_debug_abort.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Tags: no-fasttest + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +# shellcheck source=../shell_config.sh +. "$CURDIR"/../shell_config.sh + +echo 'syntax = "proto3"; + +message Message { + NotExisted x = 1; +}' > 02705_schema.proto + + +$CLICKHOUSE_LOCAL -q "select * from file(data.bin, Protobuf) settings format_schema='schema:Message'" 2>&1 | grep -c "CANNOT_PARSE_PROTOBUF_SCHEMA" + +rm 02705_schema.proto +