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

Fixed unregistered bug: Query string crashes 2.5RC1

This commit is contained in:
asfernandes 2009-12-19 01:32:00 +00:00
parent 1bef71ab0b
commit ee7fa00494
3 changed files with 51 additions and 16 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;
} }
} }