8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 04:43:03 +01:00

Fixed CORE-5480 - SUBSTRING startposition smaller than 1 should be allowed.

This commit is contained in:
Adriano dos Santos Fernandes 2017-03-01 16:11:28 +00:00
parent 41673e1d79
commit b993ed2cde

View File

@ -10282,17 +10282,6 @@ void SubstringNode::getDesc(thread_db* tdbb, CompilerScratch* csb, dsc* desc)
desc->dsc_flags |= DSC_null;
else
{
if (offsetNode->is<LiteralNode>() && desc1.dsc_dtype == dtype_long)
{
SLONG offset = MOV_get_long(&desc1, 0);
if (decrementNode && decrementNode->is<LiteralNode>() && desc3.dsc_dtype == dtype_long)
offset -= MOV_get_long(&desc3, 0);
if (offset < 0)
ERR_post(Arg::Gds(isc_bad_substring_offset) << Arg::Num(offset + 1));
}
if (length->is<LiteralNode>() && desc2.dsc_dtype == dtype_long)
{
const SLONG len = MOV_get_long(&desc2, 0);
@ -10349,20 +10338,24 @@ dsc* SubstringNode::execute(thread_db* tdbb, jrd_req* request) const
dsc* SubstringNode::perform(thread_db* tdbb, impure_value* impure, const dsc* valueDsc,
const dsc* startDsc, const dsc* lengthDsc)
{
const SLONG sStart = MOV_get_long(startDsc, 0);
const SLONG sLength = MOV_get_long(lengthDsc, 0);
SINT64 sStart = MOV_get_long(startDsc, 0);
SINT64 sLength = MOV_get_long(lengthDsc, 0);
if (sLength < 0)
status_exception::raise(Arg::Gds(isc_bad_substring_length) << Arg::Num(sLength));
if (sStart < 0)
status_exception::raise(Arg::Gds(isc_bad_substring_offset) << Arg::Num(sStart + 1));
else if (sLength < 0)
status_exception::raise(Arg::Gds(isc_bad_substring_length) << Arg::Num(sLength));
{
sLength = MAX(sLength + sStart, 0);
sStart = 1;
}
FB_UINT64 start = FB_UINT64(sStart);
FB_UINT64 length = FB_UINT64(sLength);
dsc desc;
DataTypeUtil(tdbb).makeSubstr(&desc, valueDsc, startDsc, lengthDsc);
ULONG start = (ULONG) sStart;
ULONG length = (ULONG) sLength;
if (desc.isText() && length > MAX_STR_SIZE)
length = MAX_STR_SIZE;
@ -10384,7 +10377,7 @@ dsc* SubstringNode::perform(thread_db* tdbb, impure_value* impure, const dsc* va
HalfStaticArray<UCHAR, BUFFER_LARGE> buffer;
CharSet* charSet = INTL_charset_lookup(tdbb, valueDsc->getCharSet());
const FB_UINT64 byte_offset = FB_UINT64(start) * charSet->maxBytesPerChar();
const FB_UINT64 byte_offset = start * charSet->maxBytesPerChar();
const FB_UINT64 byte_length = FB_UINT64(length) * charSet->maxBytesPerChar();
if (charSet->isMultiByte())