mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 06:43:03 +01:00
Fixed unregistered bug: Query string crashes 2.5RC1
This commit is contained in:
parent
1bef71ab0b
commit
ee7fa00494
@ -37,7 +37,7 @@ Parser::Parser(MemoryPool& pool, USHORT aClientDialect, USHORT aDbDialect, USHOR
|
|||||||
db_dialect(aDbDialect),
|
db_dialect(aDbDialect),
|
||||||
parser_version(aParserVersion),
|
parser_version(aParserVersion),
|
||||||
transformedString(pool),
|
transformedString(pool),
|
||||||
introducerMarks(pool),
|
strMarks(pool),
|
||||||
stmt_ambiguous(false)
|
stmt_ambiguous(false)
|
||||||
{
|
{
|
||||||
yyps = 0;
|
yyps = 0;
|
||||||
@ -112,15 +112,22 @@ void Parser::transformString(const char* start, unsigned length, string& dest)
|
|||||||
HalfStaticArray<char, 256> buffer;
|
HalfStaticArray<char, 256> buffer;
|
||||||
const char* pos = start;
|
const char* pos = start;
|
||||||
|
|
||||||
for (size_t i = 0; i < introducerMarks.getCount(); ++i)
|
// We need only the "introduced" strings, in the bounds of "start" and "length" and in "pos"
|
||||||
|
// order. Let collect them.
|
||||||
|
|
||||||
|
SortedArray<StrMark> introducedMarks;
|
||||||
|
|
||||||
|
GenericMap<NonPooled<dsql_str*, StrMark> >::ConstAccessor accessor(&strMarks);
|
||||||
|
for (bool found = accessor.getFirst(); found; found = accessor.getNext())
|
||||||
{
|
{
|
||||||
const IntroducerMark& mark = introducerMarks[i];
|
const StrMark& mark = accessor.current()->second;
|
||||||
|
if (mark.introduced && mark.pos >= fromBegin && mark.pos < fromBegin + length)
|
||||||
|
introducedMarks.add(mark);
|
||||||
|
}
|
||||||
|
|
||||||
if (mark.pos < fromBegin)
|
for (size_t i = 0; i < introducedMarks.getCount(); ++i)
|
||||||
continue;
|
{
|
||||||
|
const StrMark& mark = introducedMarks[i];
|
||||||
if (mark.pos >= fromBegin + length)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const char* s = lex.start + mark.pos;
|
const char* s = lex.start + mark.pos;
|
||||||
buffer.add(pos, s - pos);
|
buffer.add(pos, s - pos);
|
||||||
|
@ -91,8 +91,22 @@ private:
|
|||||||
USHORT param_number;
|
USHORT param_number;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IntroducerMark
|
struct StrMark
|
||||||
{
|
{
|
||||||
|
StrMark()
|
||||||
|
: introduced(false),
|
||||||
|
pos(0),
|
||||||
|
length(0),
|
||||||
|
str(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator >(const StrMark& o) const
|
||||||
|
{
|
||||||
|
return pos > o.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool introduced;
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
unsigned length;
|
unsigned length;
|
||||||
dsql_str* str;
|
dsql_str* str;
|
||||||
@ -156,7 +170,7 @@ private:
|
|||||||
USHORT parser_version;
|
USHORT parser_version;
|
||||||
|
|
||||||
Firebird::string transformedString;
|
Firebird::string transformedString;
|
||||||
Firebird::Array<IntroducerMark> introducerMarks;
|
Firebird::GenericMap<Firebird::NonPooled<dsql_str*, StrMark> > strMarks;
|
||||||
bool stmt_ambiguous;
|
bool stmt_ambiguous;
|
||||||
dsql_nod* DSQL_parse;
|
dsql_nod* DSQL_parse;
|
||||||
|
|
||||||
|
@ -5131,12 +5131,10 @@ sql_string
|
|||||||
str->str_charset = $1;
|
str->str_charset = $1;
|
||||||
if (str->type == dsql_str::TYPE_SIMPLE || str->type == dsql_str::TYPE_ALTERNATE)
|
if (str->type == dsql_str::TYPE_SIMPLE || str->type == dsql_str::TYPE_ALTERNATE)
|
||||||
{
|
{
|
||||||
IntroducerMark mark;
|
StrMark* mark = strMarks.get(str);
|
||||||
mark.pos = lex.last_token - lex.start;
|
fb_assert(mark);
|
||||||
mark.length = lex.ptr - lex.last_token;
|
if (mark)
|
||||||
mark.str = str;
|
mark->introduced = true;
|
||||||
|
|
||||||
introducerMarks.push(mark);
|
|
||||||
}
|
}
|
||||||
$$ = str;
|
$$ = str;
|
||||||
}
|
}
|
||||||
@ -6432,6 +6430,9 @@ int Parser::yylexAux()
|
|||||||
|
|
||||||
if (tok_class & CHR_QUOTE)
|
if (tok_class & CHR_QUOTE)
|
||||||
{
|
{
|
||||||
|
StrMark mark;
|
||||||
|
mark.pos = lex.last_token - lex.start;
|
||||||
|
|
||||||
char* buffer = string;
|
char* buffer = string;
|
||||||
size_t buffer_len = sizeof (string);
|
size_t buffer_len = sizeof (string);
|
||||||
const char* buffer_end = buffer + buffer_len - 1;
|
const char* buffer_end = buffer + buffer_len - 1;
|
||||||
@ -6519,6 +6520,11 @@ int Parser::yylexAux()
|
|||||||
yylval.legacyStr = MAKE_string(buffer, p - buffer);
|
yylval.legacyStr = MAKE_string(buffer, p - buffer);
|
||||||
if (buffer != string)
|
if (buffer != string)
|
||||||
gds__free (buffer);
|
gds__free (buffer);
|
||||||
|
|
||||||
|
mark.length = lex.ptr - lex.last_token;
|
||||||
|
mark.str = yylval.legacyStr;
|
||||||
|
strMarks.put(mark.str, mark);
|
||||||
|
|
||||||
return STRING;
|
return STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6655,6 +6661,9 @@ int Parser::yylexAux()
|
|||||||
|
|
||||||
if ((c == 'q' || c == 'Q') && lex.ptr + 3 < lex.end && *lex.ptr == '\'')
|
if ((c == 'q' || c == 'Q') && lex.ptr + 3 < lex.end && *lex.ptr == '\'')
|
||||||
{
|
{
|
||||||
|
StrMark mark;
|
||||||
|
mark.pos = lex.last_token - lex.start;
|
||||||
|
|
||||||
char endChar = *++lex.ptr;
|
char endChar = *++lex.ptr;
|
||||||
switch (endChar)
|
switch (endChar)
|
||||||
{
|
{
|
||||||
@ -6679,6 +6688,11 @@ int Parser::yylexAux()
|
|||||||
yylval.legacyStr = MAKE_string(lex.last_token + 3, lex.ptr - lex.last_token - 4);
|
yylval.legacyStr = MAKE_string(lex.last_token + 3, lex.ptr - lex.last_token - 4);
|
||||||
yylval.legacyStr->type = dsql_str::TYPE_ALTERNATE;
|
yylval.legacyStr->type = dsql_str::TYPE_ALTERNATE;
|
||||||
lex.ptr++;
|
lex.ptr++;
|
||||||
|
|
||||||
|
mark.length = lex.ptr - lex.last_token;
|
||||||
|
mark.str = yylval.legacyStr;
|
||||||
|
strMarks.put(mark.str, mark);
|
||||||
|
|
||||||
return STRING;
|
return STRING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user