From a911ea64bf4c26366afb4cbb82df8f77bafe4702 Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 12 Feb 2019 17:56:01 +0100 Subject: [PATCH] issue #8137: NULL input field generates U_ILLEGAL_ARGUMENT_ERROR (#8140) --- arangod/Aql/Functions.cpp | 33 ++++++++++++++------- tests/js/server/aql/aql-functions-string.js | 6 ++-- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 9861c5ee85..760e311b86 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -2021,12 +2021,18 @@ AqlValue Functions::Substitute(ExpressionContext* expressionContext, arangodb::velocypack::ValueLength length; char const* str = it.key.getString(length); matchPatterns.push_back(UnicodeString(str, static_cast(length))); - if (!it.value.isString()) { + if (it.value.isNull()) { + // null replacement value => replace with an empty string + replacePatterns.push_back(UnicodeString("", int32_t(0))); + } else if (it.value.isString()) { + // string case + str = it.value.getStringUnchecked(length); + replacePatterns.push_back(UnicodeString(str, static_cast(length))); + } else { + // non strings ::registerInvalidArgumentWarning(expressionContext, AFN); return AqlValue(AqlValueHintNull()); } - str = it.value.getStringUnchecked(length); - replacePatterns.push_back(UnicodeString(str, static_cast(length))); } } else { if (parameters.size() < 2) { @@ -2040,13 +2046,14 @@ AqlValue Functions::Substitute(ExpressionContext* expressionContext, VPackSlice slice = materializer.slice(search, false); if (search.isArray()) { for (auto const& it : VPackArrayIterator(slice)) { - if (!it.isString()) { + if (it.isString()) { + arangodb::velocypack::ValueLength length; + char const* str = it.getStringUnchecked(length); + matchPatterns.push_back(UnicodeString(str, static_cast(length))); + } else { ::registerInvalidArgumentWarning(expressionContext, AFN); return AqlValue(AqlValueHintNull()); } - arangodb::velocypack::ValueLength length; - char const* str = it.getStringUnchecked(length); - matchPatterns.push_back(UnicodeString(str, static_cast(length))); } } else { if (!search.isString()) { @@ -2063,13 +2070,17 @@ AqlValue Functions::Substitute(ExpressionContext* expressionContext, VPackSlice rslice = materializer2.slice(replace, false); if (replace.isArray()) { for (auto const& it : VPackArrayIterator(rslice)) { - if (!it.isString()) { + if (it.isNull()) { + // null replacement value => replace with an empty string + replacePatterns.push_back(UnicodeString("", int32_t(0))); + } else if (it.isString()) { + arangodb::velocypack::ValueLength length; + char const* str = it.getString(length); + replacePatterns.push_back(UnicodeString(str, static_cast(length))); + } else { ::registerInvalidArgumentWarning(expressionContext, AFN); return AqlValue(AqlValueHintNull()); } - arangodb::velocypack::ValueLength length; - char const* str = it.getString(length); - replacePatterns.push_back(UnicodeString(str, static_cast(length))); } } else if (replace.isString()) { // If we have a string as replacement, diff --git a/tests/js/server/aql/aql-functions-string.js b/tests/js/server/aql/aql-functions-string.js index 2e8a80baab..0df65e0ed5 100644 --- a/tests/js/server/aql/aql-functions-string.js +++ b/tests/js/server/aql/aql-functions-string.js @@ -1191,7 +1191,9 @@ function ahuacatlStringFunctionsTestSuite () { [ 'aaaayyybccc', 'aaaabbbbccc', [ 'A', 'b', 'c' ], [ 'x', 'y', 'z' ], 3 ], [ 'the quick foxx', 'the quick brown foxx', 'brown' ], [ 'the quick brown foxx', 'the quick brown foxx', [ ] ], - [ 'the quick foxx', 'the quick brown foxx', [ 'brown' ], [ ] ] + [ 'the quick foxx', 'the quick brown foxx', [ 'brown' ], [ ] ], + [ 'the ant', 'the quick brown foxx', [ 'quick', 'brown', 'foxx' ], [ '', null, 'ant' ] ], + [ 'the ant', 'the quick brown foxx', { quick: '', brown: null, foxx: 'ant' } ], ]; values.forEach(function (value) { @@ -1206,7 +1208,7 @@ function ahuacatlStringFunctionsTestSuite () { assertEqual([ expected ], nuResults, value); }); }, - + // ////////////////////////////////////////////////////////////////////////////// // / @brief test substitute function // //////////////////////////////////////////////////////////////////////////////