Skip to content

Commit b993ed2

Browse files
committed
Fixed CORE-5480 - SUBSTRING startposition smaller than 1 should be allowed.
1 parent 41673e1 commit b993ed2

File tree

1 file changed

+13
-20
lines changed

1 file changed

+13
-20
lines changed

src/dsql/ExprNodes.cpp

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10282,17 +10282,6 @@ void SubstringNode::getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc)
1028210282
desc->dsc_flags |= DSC_null;
1028310283
else
1028410284
{
10285-
if (offsetNode->is<LiteralNode>() && desc1.dsc_dtype == dtype_long)
10286-
{
10287-
SLONG offset = MOV_get_long(&desc1, 0);
10288-
10289-
if (decrementNode && decrementNode->is<LiteralNode>() && desc3.dsc_dtype == dtype_long)
10290-
offset -= MOV_get_long(&desc3, 0);
10291-
10292-
if (offset < 0)
10293-
ERR_post(Arg::Gds(isc_bad_substring_offset) << Arg::Num(offset + 1));
10294-
}
10295-
1029610285
if (length->is<LiteralNode>() && desc2.dsc_dtype == dtype_long)
1029710286
{
1029810287
const SLONG len = MOV_get_long(&desc2, 0);
@@ -10349,20 +10338,24 @@ dsc* SubstringNode::execute(thread_db* tdbb, jrd_req* request) const
1034910338
dsc* SubstringNode::perform(thread_db* tdbb, impure_value* impure, const dsc* valueDsc,
1035010339
const dsc* startDsc, const dsc* lengthDsc)
1035110340
{
10352-
const SLONG sStart = MOV_get_long(startDsc, 0);
10353-
const SLONG sLength = MOV_get_long(lengthDsc, 0);
10341+
SINT64 sStart = MOV_get_long(startDsc, 0);
10342+
SINT64 sLength = MOV_get_long(lengthDsc, 0);
1035410343

10355-
if (sStart < 0)
10356-
status_exception::raise(Arg::Gds(isc_bad_substring_offset) << Arg::Num(sStart + 1));
10357-
else if (sLength < 0)
10344+
if (sLength < 0)
1035810345
status_exception::raise(Arg::Gds(isc_bad_substring_length) << Arg::Num(sLength));
1035910346

10347+
if (sStart < 0)
10348+
{
10349+
sLength = MAX(sLength + sStart, 0);
10350+
sStart = 1;
10351+
}
10352+
10353+
FB_UINT64 start = FB_UINT64(sStart);
10354+
FB_UINT64 length = FB_UINT64(sLength);
10355+
1036010356
dsc desc;
1036110357
DataTypeUtil(tdbb).makeSubstr(&desc, valueDsc, startDsc, lengthDsc);
1036210358

10363-
ULONG start = (ULONG) sStart;
10364-
ULONG length = (ULONG) sLength;
10365-
1036610359
if (desc.isText() && length > MAX_STR_SIZE)
1036710360
length = MAX_STR_SIZE;
1036810361

@@ -10384,7 +10377,7 @@ dsc* SubstringNode::perform(thread_db* tdbb, impure_value* impure, const dsc* va
1038410377
HalfStaticArray<UCHAR, BUFFER_LARGE> buffer;
1038510378
CharSet* charSet = INTL_charset_lookup(tdbb, valueDsc->getCharSet());
1038610379

10387-
const FB_UINT64 byte_offset = FB_UINT64(start) * charSet->maxBytesPerChar();
10380+
const FB_UINT64 byte_offset = start * charSet->maxBytesPerChar();
1038810381
const FB_UINT64 byte_length = FB_UINT64(length) * charSet->maxBytesPerChar();
1038910382

1039010383
if (charSet->isMultiByte())

0 commit comments

Comments
 (0)