Skip to content

Commit

Permalink
[CBRD-24631] Fix segfault when an error occurs with return_null_on_fu…
Browse files Browse the repository at this point in the history
…nction_errors is on (#4068)

http://jira.cubrid.org/browse/CBRD-24631

backport of #4062
  • Loading branch information
hgryoo authored Jan 20, 2023
1 parent 1fd92ad commit 3565885
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/query/query_opfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -8568,7 +8568,7 @@ qdata_regexp_function (THREAD_ENTRY * thread_p, FUNCTION_TYPE * function_p, VAL_
function_p->tmp_obj->compiled_regex = new cub_compiled_regex ();
}

cub_compiled_regex *compiled_regex = function_p->tmp_obj->compiled_regex;
cub_compiled_regex *&compiled_regex = function_p->tmp_obj->compiled_regex;
error_status = regexp_func (function_p->value, args, no_args, &compiled_regex);
if (error_status != NO_ERROR)
{
Expand Down
47 changes: 28 additions & 19 deletions src/query/string_opfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4559,31 +4559,31 @@ db_string_rlike (const DB_VALUE * src, const DB_VALUE * pattern, const DB_VALUE
error_status = cubregex::compile (compiled_regex, pattern_string, match_str, collation);
if (error_status != NO_ERROR)
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto cleanup;
}

std::string src_string (db_get_string (src), db_get_string_size (src));
error_status = cubregex::search (*result, *compiled_regex, src_string);
if (error_status != NO_ERROR)
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto cleanup;
}
}

cleanup:
if (error_status != NO_ERROR)
{
*result = V_ERROR;
comp_regex = NULL;
if (prm_get_bool_value (PRM_ID_RETURN_NULL_ON_FUNCTION_ERRORS))
{
/* we must not return an error code */
*result = V_UNKNOWN;
er_clear ();
error_status = NO_ERROR;
}
else
{
(error_status == ER_QSTR_BAD_SRC_CODESET) ? error_status = NO_ERROR : *result = V_ERROR;
}
}

if (comp_regex == NULL)
Expand Down Expand Up @@ -4734,7 +4734,6 @@ db_string_regexp_count (DB_VALUE * result, DB_VALUE * args[], int const num_args
error_status = cubregex::compile (compiled_regex, pattern_string, match_type_str, collation);
if (error_status != NO_ERROR)
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto exit;
}

Expand All @@ -4745,7 +4744,6 @@ db_string_regexp_count (DB_VALUE * result, DB_VALUE * args[], int const num_args
if (error_status != NO_ERROR)
{
/* regex execution error */
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto exit;
}

Expand All @@ -4758,13 +4756,16 @@ db_string_regexp_count (DB_VALUE * result, DB_VALUE * args[], int const num_args
if (error_status != NO_ERROR)
{
db_make_int (result, 0);
comp_regex = NULL;
if (prm_get_bool_value (PRM_ID_RETURN_NULL_ON_FUNCTION_ERRORS))
{
/* we must not return an error code */
er_clear ();
error_status = NO_ERROR;
}
else
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
}
}

if (comp_regex == NULL)
Expand Down Expand Up @@ -4949,7 +4950,6 @@ db_string_regexp_instr (DB_VALUE * result, DB_VALUE * args[], int const num_args
error_status = cubregex::compile (compiled_regex, pattern_string, match_type_str, collation);
if (error_status != NO_ERROR)
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto exit;
}

Expand All @@ -4961,7 +4961,6 @@ db_string_regexp_instr (DB_VALUE * result, DB_VALUE * args[], int const num_args
if (error_status != NO_ERROR)
{
/* regex execution error */
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto exit;
}

Expand All @@ -4973,14 +4972,18 @@ db_string_regexp_instr (DB_VALUE * result, DB_VALUE * args[], int const num_args
exit:
if (error_status != NO_ERROR)
{
db_make_null (result);
comp_regex = NULL;
if (prm_get_bool_value (PRM_ID_RETURN_NULL_ON_FUNCTION_ERRORS))
{
/* we must not return an error code */
db_make_null (result);
er_clear ();
error_status = NO_ERROR;
}
else
{
db_make_int (result, 0);
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
}
}

if (comp_regex == NULL)
Expand Down Expand Up @@ -5113,7 +5116,6 @@ db_string_regexp_like (DB_VALUE * result, DB_VALUE * args[], int const num_args,
error_status = cubregex::compile (compiled_regex, pattern_string, match_type_str, collation);
if (error_status != NO_ERROR)
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto exit;
}

Expand All @@ -5124,7 +5126,6 @@ db_string_regexp_like (DB_VALUE * result, DB_VALUE * args[], int const num_args,
if (error_status != NO_ERROR)
{
/* regex execution error */
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto exit;
}

Expand All @@ -5137,13 +5138,17 @@ db_string_regexp_like (DB_VALUE * result, DB_VALUE * args[], int const num_args,
if (error_status != NO_ERROR)
{
db_make_null (result);
comp_regex = NULL;
if (prm_get_bool_value (PRM_ID_RETURN_NULL_ON_FUNCTION_ERRORS))
{
/* we must not return an error code */
er_clear ();
error_status = NO_ERROR;
}
else
{
db_make_int (result, 0);
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
}
}

if (comp_regex == NULL)
Expand Down Expand Up @@ -5328,7 +5333,6 @@ db_string_regexp_replace (DB_VALUE * result, DB_VALUE * args[], int const num_ar
error_status = cubregex::compile (compiled_regex, pattern_string, match_type_str, collation);
if (error_status != NO_ERROR)
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto exit;
}

Expand Down Expand Up @@ -5393,13 +5397,16 @@ db_string_regexp_replace (DB_VALUE * result, DB_VALUE * args[], int const num_ar
if (error_status != NO_ERROR)
{
db_make_null (result);
comp_regex = NULL;
if (prm_get_bool_value (PRM_ID_RETURN_NULL_ON_FUNCTION_ERRORS))
{
/* we must not return an error code */
er_clear ();
error_status = NO_ERROR;
}
else
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
}
}

if (comp_regex == NULL)
Expand Down Expand Up @@ -5566,7 +5573,6 @@ db_string_regexp_substr (DB_VALUE * result, DB_VALUE * args[], int const num_arg
error_status = cubregex::compile (compiled_regex, pattern_string, match_type_str, collation);
if (error_status != NO_ERROR)
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto exit;
}

Expand All @@ -5579,7 +5585,6 @@ db_string_regexp_substr (DB_VALUE * result, DB_VALUE * args[], int const num_arg
if (error_status != NO_ERROR)
{
/* regex execution error */
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
goto exit;
}

Expand Down Expand Up @@ -5609,19 +5614,23 @@ db_string_regexp_substr (DB_VALUE * result, DB_VALUE * args[], int const num_arg
if (error_status != NO_ERROR)
{
db_make_null (result);
comp_regex = NULL;
if (prm_get_bool_value (PRM_ID_RETURN_NULL_ON_FUNCTION_ERRORS))
{
/* we must not return an error code */
er_clear ();
error_status = NO_ERROR;
}
else
{
error_status = (error_status == ER_QSTR_BAD_SRC_CODESET) ? NO_ERROR : error_status;
}
}

if (comp_regex == NULL)
{
/* free memory if this function is invoked in constant folding */
delete compiled_regex;
compiled_regex = NULL;
}
else
{
Expand Down
21 changes: 11 additions & 10 deletions src/query/string_regex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,22 @@ namespace cubregex
switch (type)
{
case engine_type::LIB_CPPSTD:
delete compiled->std_obj;
if (compiled->std_obj)
{
delete compiled->std_obj;
}
break;
case engine_type::LIB_RE2:
delete compiled->re2_obj;
if (compiled->re2_obj)
{
delete compiled->re2_obj;
}
break;
default:
assert (false);
}
delete compiled;
compiled = {nullptr};
}
}

Expand Down Expand Up @@ -264,16 +271,10 @@ namespace cubregex
// delete previous compiled object
if (cr)
{
if (cr->compiled)
{
delete cr->compiled;
}
}
else
{
cr = new compiled_regex ();
delete cr;
}

cr = new compiled_regex ();
cr->type = type;
cr->compiled = new compiled_regex_object { nullptr };
cr->pattern.assign (pattern_string);
Expand Down
2 changes: 1 addition & 1 deletion src/query/string_regex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ namespace cubregex

compiled_regex ()
: type (LIB_NONE)
, compiled (nullptr)
, compiled {nullptr}
, pattern ()
, flags (0)
, codeset (INTL_CODESET_NONE)
Expand Down
10 changes: 6 additions & 4 deletions src/query/string_regex_std.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ namespace cubregex

try
{
cub_std_regex &std_reg = * (reg.compiled->std_obj);
cub_std_regex &std_reg = GET_STD_OBJ (reg);

#if defined(WINDOWS)
/* HACK: case insensitive doesn't work well on Windows.
* This code transforms source string into lowercase
Expand Down Expand Up @@ -199,7 +200,8 @@ namespace cubregex
src_wstring.substr (position, src_wstring.size () - position)
);

cub_std_regex &std_reg = * (reg.compiled->std_obj);
cub_std_regex &std_reg = GET_STD_OBJ (reg);

#if defined(WINDOWS)
/* HACK: case insensitive doesn't work well on Windows.
* This code transforms source string into lowercase
Expand Down Expand Up @@ -258,7 +260,7 @@ namespace cubregex
src_wstring.substr (position, src_wstring.size () - position)
);

cub_std_regex &std_reg = * (reg.compiled->std_obj);
cub_std_regex &std_reg = GET_STD_OBJ (reg);
#if defined(WINDOWS)
/* HACK: case insensitive doesn't work well on Windows.
* This code transforms source string into lowercase
Expand Down Expand Up @@ -572,7 +574,7 @@ namespace cubregex
src_wstring.substr (position, src_wstring.size () - position)
);

cub_std_regex &std_reg = * (reg.compiled->std_obj);
cub_std_regex &std_reg = GET_STD_OBJ (reg);

#if defined(WINDOWS)
/* HACK: case insensitive doesn't work well on Windows.
Expand Down

0 comments on commit 3565885

Please sign in to comment.