From 0a2e9760ee72ab9b5652d296dcf6af04b92fc89f Mon Sep 17 00:00:00 2001 From: Sergey Zefirov <72864488+mariadb-SergeyZefirov@users.noreply.github.com> Date: Wed, 31 May 2023 15:30:40 +0300 Subject: [PATCH] Fix for JSON_VALUE function to remove OOB stack access (#2852) MCOL-271 introduced a bug in JSON_VALUE that was discovered during implementation of ASAN builds. The changes here restore normal functionality. In short, changes in MCOL-271 introduced a local variable instead of reference to a string in ConstantColumn's fResult.strVal. The handling of ConstantColumn is different because ConstantColumn's value is used to initialize JSON path once. JSON path value holds pointer to data it does not own and if there are two or more rows the data can be corrupted and/or be out of stack bounds. The changes here introduce reference to a NullString that is held in the ConstantColumn's fResult.strVal and uses appropriate functions to obtain data from the NullString. CC's fResult is held by CC and strVal is also neither changing nor moving during operation, which allow JSON path to hold correct pointers during multi-row operation. --- utils/funcexp/func_json_value.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/utils/funcexp/func_json_value.cpp b/utils/funcexp/func_json_value.cpp index c05a010aa..9fa6d0cde 100644 --- a/utils/funcexp/func_json_value.cpp +++ b/utils/funcexp/func_json_value.cpp @@ -64,8 +64,7 @@ bool JSONPathWrapper::extract(std::string& ret, rowgroup::Row& row, execplan::SP bool isNullJS = false, isNullPath = false; const string js = funcParamJS->data()->getStrVal(row, isNullJS).safeString(""); - const string sjsp = funcParamPath->data()->getStrVal(row, isNullPath).safeString(""); - const string_view jsp = sjsp; + const utils::NullString& sjsp = funcParamPath->data()->getStrVal(row, isNullPath); if (isNullJS || isNullPath) return true; @@ -79,8 +78,8 @@ bool JSONPathWrapper::extract(std::string& ret, rowgroup::Row& row, execplan::SP constant = (constCol != nullptr); } - if (isNullPath || json_path_setup(&p, getCharset(funcParamPath), (const uchar*)jsp.data(), - (const uchar*)jsp.data() + jsp.size())) + if (isNullPath || json_path_setup(&p, getCharset(funcParamPath), (const uchar*)sjsp.str(), + (const uchar*)sjsp.end())) return true; parsed = constant;