From 20f49566a207ecf1fd39d5a7777946063665650a Mon Sep 17 00:00:00 2001 From: Eliran Sinvani Date: Wed, 3 Oct 2018 14:38:04 +0300 Subject: [PATCH] cql3 : add workaround to antlr3 null dereference bug The Antlr3 exception class has a null dereference bug that crashes the system when trying to extract the exception message using ANTLR_Exception<...>::displayRecognitionError(...) function. When a parsing error occurs the CqlParser throws an exception which in turn processesed for some special cases in scylla to generate a custom message. The default case however, creates the message using displayRecognitionError, causing the system to crash. The fix is a simple workaround, making sure the pointer is not null before the call to the function. A "proper" fix can't be implemented because the exception class itself is implemented outside scylla in antlr headers that resides on the host machine os. Tested manualy 2 testcases, a typo causing scylla to crash and a cql comment without a newline at the end also caused scylla to crash. Ran unit tests (release). Fixes #3740 Fixes #3764 Signed-off-by: Eliran Sinvani Message-Id: --- cql3/error_collector.hh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cql3/error_collector.hh b/cql3/error_collector.hh index 9a49714c78..2a83d6e042 100644 --- a/cql3/error_collector.hh +++ b/cql3/error_collector.hh @@ -67,6 +67,12 @@ class error_collector : public error_listener */ const sstring_view _query; + /** + * An empty bitset to be used as a workaround for AntLR null dereference + * bug. + */ + static typename ExceptionBaseType::BitsetListType _empty_bit_list; + public: /** @@ -144,6 +150,14 @@ private: break; } default: + // AntLR Exception class has a bug of dereferencing a null + // pointer in the displayRecognitionError. The following + // if statement makes sure it will not be null before the + // call to that function (displayRecognitionError). + // bug reference: https://github.com/antlr/antlr3/issues/191 + if (!ex->get_expectingSet()) { + ex->set_expectingSet(&_empty_bit_list); + } ex->displayRecognitionError(token_names, msg); } return msg.str(); @@ -345,4 +359,8 @@ private: #endif }; +template +typename ExceptionBaseType::BitsetListType +error_collector::_empty_bit_list = typename ExceptionBaseType::BitsetListType(); + }