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

Fixed CORE-4811: Make user names behave according to SQL identifiers rules

This commit is contained in:
alexpeshkoff 2015-06-03 13:57:18 +00:00
parent ebdf793154
commit 1b6632ac8b
35 changed files with 623 additions and 1741 deletions

View File

@ -31,6 +31,10 @@
#include "../common/classes/auto.h"
#include "../common/SimpleStatusVector.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
int CLIB_ROUTINE main(int argc, char* argv[])
{
@ -44,6 +48,11 @@ int CLIB_ROUTINE main(int argc, char* argv[])
* Invoke real gfix main function
*
**************************************/
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
try
{
Firebird::AutoPtr<Firebird::UtilSvc> uSvc(Firebird::UtilSvc::createStandalone(argc, argv));

View File

@ -342,8 +342,6 @@ int SecurityDatabase::verify(IWriter* authBlock, IServerBlock* sBlock)
return IAuth::AUTH_MORE_DATA;
}
login.upper();
// Look up the user name in the userinfo database and use the parameters
// found there. This means that another database must be accessed, and
// that means the current context must be saved and restored.

View File

@ -31,6 +31,9 @@
#include "../common/classes/auto.h"
#include "../common/SimpleStatusVector.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
int CLIB_ROUTINE main( int argc, char* argv[])
{
@ -44,6 +47,11 @@ int CLIB_ROUTINE main( int argc, char* argv[])
* Invoke real gbak main function
*
**************************************/
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
try
{
Firebird::AutoPtr<Firebird::UtilSvc> uSvc(Firebird::UtilSvc::createStandalone(argc, argv));

View File

@ -59,6 +59,10 @@
#include <io.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
static const int mode_read = O_RDONLY;
static const int mode_write = O_WRONLY | O_CREAT;
static const int mask = 0666;
@ -188,6 +192,11 @@ static int write_header(const b_fil*, header_rec, FILE_DESC, TEXT*);
int main( int argc, char* argv[])
{
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
const SCHAR* const prog_name = argv[0];
if (argc < 2)

View File

@ -67,7 +67,7 @@ void WriterImplementation::add(Firebird::CheckStatusWrapper* st, const char* nam
putLevel();
current.clear();
current.insertString(AuthReader::AUTH_NAME, name);
current.insertString(AuthReader::AUTH_NAME, name, strlen(name));
fb_assert(plugin.hasData());
if (plugin.hasData())
{

View File

@ -85,20 +85,6 @@ public:
static ULONG toUpper(Jrd::CharSet* cs, ULONG srcLen, const UCHAR* src, ULONG dstLen, UCHAR* dst,
const ULONG* exceptions);
template <typename STR>
static void toUpper(STR& s, Jrd::CharSet* cs = getUtf8CharSet())
{
HalfStaticArray<UCHAR, BUFFER_SMALL> buffer;
FB_SIZE_T len = s.length();
ULONG count = toUpper(cs, len, reinterpret_cast<const UCHAR*>(s.c_str()), len * 4,
buffer.getBuffer(len * 4), NULL);
if (count != INTL_BAD_STR_LENGTH)
s.assign(reinterpret_cast<const char*>(buffer.begin()), count);
else
fb_assert(false);
}
static bool readOneChar(Jrd::CharSet* cs, const UCHAR** s, const UCHAR* end, ULONG* size);
static bool setupIcuAttributes(charset* cs, const string& specificAttributes,

168
src/common/Tokens.cpp Normal file
View File

@ -0,0 +1,168 @@
/*
* PROGRAM: String parser
* MODULE: Tokens.cpp
* DESCRIPTION: Enhanced variant of strtok()
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2015 Alex Peshkov <peshkoff at mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include "../common/Tokens.h"
#include "../common/StatusArg.h"
namespace Firebird {
Tokens::Tokens(FB_SIZE_T length, const char* toParse, const char* spaces, const char* quotes, const Comment* comments)
: tokens(getPool()), str(getPool())
{
if (!length)
length = strlen(toParse);
str.assign(toParse, length);
char inStr = 0;
Tok* inToken = NULL;
FB_SIZE_T startp = 0;
FB_SIZE_T origin = 0;
FB_SIZE_T p = 0;
while (p < str.length())
{
if (comments && !inStr)
{
for (const Comment* comm = comments; comm->start; ++comm)
{
if (strncmp(comm->start, &str[p], strlen(comm->start)) == 0)
{
FB_SIZE_T p2 = p + strlen(comm->start);
p2 = str.find(comm->stop, p2);
if (p2 == str.npos)
error("Missing close comment for %s", comm->start);
p2 += strlen(comm->stop);
str.erase(p, p2 - p);
origin += (p2 - p);
continue;
}
}
}
char c = str[p];
if (inStr)
{
if (c == inStr)
{
++p;
++origin;
if (p >= str.length() || str[p] != inStr)
{
inStr = 0;
inToken->length = p - startp;
inToken = NULL;
continue;
}
// double quote - continue processing string
}
++p;
++origin;
continue;
}
bool space = spaces && strchr(spaces, c);
if (space)
{
if (inToken)
{
inToken->length = p - startp;
inToken = NULL;
}
++p;
++origin;
continue;
}
bool quote = quotes && strchr(quotes, c);
if (quote)
{
if (inToken)
{
inToken->length = p - startp;
inToken = NULL;
}
// start string
inStr = c;
}
if (!inToken)
{
// start token
startp = p;
tokens.grow(tokens.getCount() + 1);
inToken = &tokens[tokens.getCount() - 1];
inToken->text = &str[p];
inToken->origin = origin;
}
// done with char
++p;
++origin;
}
if (inStr)
error("Missing close quote <%c>", inStr);
if (inToken)
inToken->length = p - startp;
}
void Tokens::error(const char* fmt, ...)
{
string buffer;
va_list params;
va_start(params, fmt);
buffer.vprintf(fmt, params);
va_end(params);
(Arg::Gds(isc_random) << "Parse to tokens error" << Arg::Gds(isc_random) << buffer).raise();
}
string Tokens::Tok::stripped() const
{
string rc;
char q = text[0];
for (FB_SIZE_T i = 1; i < length - 1; ++i)
{
if (text[i] == q)
++i;
rc += text[i];
}
return rc;
}
Tokens::Comment sqlComments[3] = {
{ "/*", "*/" },
{ "--", "\n" },
{ NULL, NULL }
};
const char* sqlSpaces = " \t\r\n";
} // namespace Firebird

79
src/common/Tokens.h Normal file
View File

@ -0,0 +1,79 @@
/*
* PROGRAM: String parser
* MODULE: Tokens.h
* DESCRIPTION: Enhanced variant of strtok()
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2015 Alex Peshkov <peshkoff at mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*
*/
#ifndef FB_TOKENS_H
#define FB_TOKENS_H
#include "firebird/Interface.h"
#include "../common/classes/array.h"
#include "../common/classes/fb_string.h"
namespace Firebird {
class Tokens : public AutoStorage
{
public:
struct Comment
{
const char* start;
const char* stop;
};
Tokens(FB_SIZE_T length, const char* string, const char* spaces, const char* quotes, const Comment* comments);
struct Tok
{
const char* text;
FB_SIZE_T length, origin;
string stripped() const;
};
const Tok& operator[](FB_SIZE_T pos) const
{
return tokens[pos];
}
FB_SIZE_T getCount() const
{
return tokens.getCount();
}
private:
static void error(const char* fmt, ...);
HalfStaticArray<Tok, 16> tokens;
string str;
};
extern Tokens::Comment sqlComments[3];
extern const char* sqlSpaces;
} // namespace Firebird
#endif // FB_AUTH_H

View File

@ -45,7 +45,6 @@ void ISC_systemToUtf8(Firebird::AbstractString& str);
void ISC_utf8ToSystem(Firebird::AbstractString& str);
void ISC_escape(Firebird::AbstractString& str);
void ISC_unescape(Firebird::AbstractString& str);
void ISC_utf8Upper(Firebird::AbstractString& str);
// This form of ISC_expand_filename makes epp files happy
inline bool ISC_expand_filename(const TEXT* unexpanded, USHORT len_unexpanded,

View File

@ -86,7 +86,6 @@
#endif
#include "../common/config/config.h"
#include "../common/unicodeUpper.h"
const char INET_FLAG = ':';
@ -1692,12 +1691,10 @@ class Converters
public:
explicit Converters(MemoryPool& p)
: systemToUtf8(p, IConv::SYSTEM, "UTF-8"),
utf8ToSystem(p, "UTF-8", IConv::SYSTEM),
unicodeToUtf8(p, "UNICODE", "UTF-8"),
utf8ToUnicode(p, "UTF-8", "UNICODE")
utf8ToSystem(p, "UTF-8", IConv::SYSTEM)
{ }
IConv systemToUtf8, utf8ToSystem, unicodeToUtf8, utf8ToUnicode;
IConv systemToUtf8, utf8ToSystem;
};
@ -1806,47 +1803,6 @@ private:
#endif // WIN_NT
void ISC_utf8Upper(Firebird::AbstractString& str)
{
if (str.isEmpty())
return;
#if defined(WIN_NT)
WideCharBuffer<256> wBuffer;
bool error = !wBuffer.fromString(CP_UTF8, str);
if (!error)
{
WCHAR* wch = wBuffer.getBuffer();
const WCHAR* const end = wch + wBuffer.getLength();
for (; wch < end; wch++)
*wch = unicodeUpper(*wch);
error = !wBuffer.toString(CP_UTF8, str);
}
if (error)
{
DWORD errCode = GetLastError();
status_exception::raise(
Arg::Gds(isc_bad_conn_str) << Arg::Gds(isc_transliteration_failed) <<
Arg::Windows(errCode));
}
#elif defined(HAVE_ICONV_H)
iConv().utf8ToUnicode.convert(str);
{ // aligner scope
Firebird::BiAligner<unsigned short> alignedStr(reinterpret_cast<UCHAR*>(str.begin()), str.length());
unsigned short* const end = alignedStr + (str.length() / 2);
for (unsigned short* begin = alignedStr; begin < end; ++begin)
*begin = unicodeUpper(*begin);
}
iConv().unicodeToUtf8.convert(str);
#endif // HAVE_ICONV_H
}
// Converts a string from the system charset to UTF-8.
void ISC_systemToUtf8(Firebird::AbstractString& str)
{

View File

@ -1,727 +0,0 @@
/*
* PROGRAM: Firebird generic routine
* MODULE: unicodeUpper.cpp
* DESCRIPTION: Converts unicode character to uppercase.
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2015 Alex Peshkov <peshkoff at mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include "../common/unicodeUpper.h"
namespace
{
// Conversion table based on:
// http://www-01.ibm.com/support/knowledgecenter/ssw_i5_54/nls/rbagslowtoupmaptable.htm
unsigned short table[] = {
0x0061, 0x0041,
0x0062, 0x0042,
0x0063, 0x0043,
0x0064, 0x0044,
0x0065, 0x0045,
0x0066, 0x0046,
0x0067, 0x0047,
0x0068, 0x0048,
0x0069, 0x0049,
0x006A, 0x004A,
0x006B, 0x004B,
0x006C, 0x004C,
0x006D, 0x004D,
0x006E, 0x004E,
0x006F, 0x004F,
0x0070, 0x0050,
0x0071, 0x0051,
0x0072, 0x0052,
0x0073, 0x0053,
0x0074, 0x0054,
0x0075, 0x0055,
0x0076, 0x0056,
0x0077, 0x0057,
0x0078, 0x0058,
0x0079, 0x0059,
0x007A, 0x005A,
0x00E0, 0x00C0,
0x00E1, 0x00C1,
0x00E2, 0x00C2,
0x00E3, 0x00C3,
0x00E4, 0x00C4,
0x00E5, 0x00C5,
0x00E6, 0x00C6,
0x00E7, 0x00C7,
0x00E8, 0x00C8,
0x00E9, 0x00C9,
0x00EA, 0x00CA,
0x00EB, 0x00CB,
0x00EC, 0x00CC,
0x00ED, 0x00CD,
0x00EE, 0x00CE,
0x00EF, 0x00CF,
0x00F0, 0x00D0,
0x00F1, 0x00D1,
0x00F2, 0x00D2,
0x00F3, 0x00D3,
0x00F4, 0x00D4,
0x00F5, 0x00D5,
0x00F6, 0x00D6,
0x00F8, 0x00D8,
0x00F9, 0x00D9,
0x00FA, 0x00DA,
0x00FB, 0x00DB,
0x00FC, 0x00DC,
0x00FD, 0x00DD,
0x00FE, 0x00DE,
0x00FF, 0x0178,
0x0101, 0x0100,
0x0103, 0x0102,
0x0105, 0x0104,
0x0107, 0x0106,
0x0109, 0x0108,
0x010B, 0x010A,
0x010D, 0x010C,
0x010F, 0x010E,
0x0111, 0x0110,
0x0113, 0x0112,
0x0115, 0x0114,
0x0117, 0x0116,
0x0119, 0x0118,
0x011B, 0x011A,
0x011D, 0x011C,
0x011F, 0x011E,
0x0121, 0x0120,
0x0123, 0x0122,
0x0125, 0x0124,
0x0127, 0x0126,
0x0129, 0x0128,
0x012B, 0x012A,
0x012D, 0x012C,
0x012F, 0x012E,
0x0131, 0x0049,
0x0133, 0x0132,
0x0135, 0x0134,
0x0137, 0x0136,
0x013A, 0x0139,
0x013C, 0x013B,
0x013E, 0x013D,
0x0140, 0x013F,
0x0142, 0x0141,
0x0144, 0x0143,
0x0146, 0x0145,
0x0148, 0x0147,
0x014B, 0x014A,
0x014D, 0x014C,
0x014F, 0x014E,
0x0151, 0x0150,
0x0153, 0x0152,
0x0155, 0x0154,
0x0157, 0x0156,
0x0159, 0x0158,
0x015B, 0x015A,
0x015D, 0x015C,
0x015F, 0x015E,
0x0161, 0x0160,
0x0163, 0x0162,
0x0165, 0x0164,
0x0167, 0x0166,
0x0169, 0x0168,
0x016B, 0x016A,
0x016D, 0x016C,
0x016F, 0x016E,
0x0171, 0x0170,
0x0173, 0x0172,
0x0175, 0x0174,
0x0177, 0x0176,
0x017A, 0x0179,
0x017C, 0x017B,
0x017E, 0x017D,
0x0183, 0x0182,
0x0185, 0x0184,
0x0188, 0x0187,
0x018C, 0x018B,
0x0192, 0x0191,
0x0199, 0x0198,
0x01A1, 0x01A0,
0x01A3, 0x01A2,
0x01A5, 0x01A4,
0x01A8, 0x01A7,
0x01AD, 0x01AC,
0x01B0, 0x01AF,
0x01B4, 0x01B3,
0x01B6, 0x01B5,
0x01B9, 0x01B8,
0x01BD, 0x01BC,
0x01C6, 0x01C4,
0x01C9, 0x01C7,
0x01CC, 0x01CA,
0x01CE, 0x01CD,
0x01D0, 0x01CF,
0x01D2, 0x01D1,
0x01D4, 0x01D3,
0x01D6, 0x01D5,
0x01D8, 0x01D7,
0x01DA, 0x01D9,
0x01DC, 0x01DB,
0x01DF, 0x01DE,
0x01E1, 0x01E0,
0x01E3, 0x01E2,
0x01E5, 0x01E4,
0x01E7, 0x01E6,
0x01E9, 0x01E8,
0x01EB, 0x01EA,
0x01ED, 0x01EC,
0x01EF, 0x01EE,
0x01F3, 0x01F1,
0x01F5, 0x01F4,
0x01FB, 0x01FA,
0x01FD, 0x01FC,
0x01FF, 0x01FE,
0x0201, 0x0200,
0x0203, 0x0202,
0x0205, 0x0204,
0x0207, 0x0206,
0x0209, 0x0208,
0x020B, 0x020A,
0x020D, 0x020C,
0x020F, 0x020E,
0x0211, 0x0210,
0x0213, 0x0212,
0x0215, 0x0214,
0x0217, 0x0216,
0x0253, 0x0181,
0x0254, 0x0186,
0x0257, 0x018A,
0x0258, 0x018E,
0x0259, 0x018F,
0x025B, 0x0190,
0x0260, 0x0193,
0x0263, 0x0194,
0x0268, 0x0197,
0x0269, 0x0196,
0x026F, 0x019C,
0x0272, 0x019D,
0x0275, 0x019F,
0x0283, 0x01A9,
0x0288, 0x01AE,
0x028A, 0x01B1,
0x028B, 0x01B2,
0x0292, 0x01B7,
0x03AC, 0x0386,
0x03AD, 0x0388,
0x03AE, 0x0389,
0x03AF, 0x038A,
0x03B1, 0x0391,
0x03B2, 0x0392,
0x03B3, 0x0393,
0x03B4, 0x0394,
0x03B5, 0x0395,
0x03B6, 0x0396,
0x03B7, 0x0397,
0x03B8, 0x0398,
0x03B9, 0x0399,
0x03BA, 0x039A,
0x03BB, 0x039B,
0x03BC, 0x039C,
0x03BD, 0x039D,
0x03BE, 0x039E,
0x03BF, 0x039F,
0x03C0, 0x03A0,
0x03C1, 0x03A1,
0x03C3, 0x03A3,
0x03C4, 0x03A4,
0x03C5, 0x03A5,
0x03C6, 0x03A6,
0x03C7, 0x03A7,
0x03C8, 0x03A8,
0x03C9, 0x03A9,
0x03CA, 0x03AA,
0x03CB, 0x03AB,
0x03CC, 0x038C,
0x03CD, 0x038E,
0x03CE, 0x038F,
0x03E3, 0x03E2,
0x03E5, 0x03E4,
0x03E7, 0x03E6,
0x03E9, 0x03E8,
0x03EB, 0x03EA,
0x03ED, 0x03EC,
0x03EF, 0x03EE,
0x0430, 0x0410,
0x0431, 0x0411,
0x0432, 0x0412,
0x0433, 0x0413,
0x0434, 0x0414,
0x0435, 0x0415,
0x0436, 0x0416,
0x0437, 0x0417,
0x0438, 0x0418,
0x0439, 0x0419,
0x043A, 0x041A,
0x043B, 0x041B,
0x043C, 0x041C,
0x043D, 0x041D,
0x043E, 0x041E,
0x043F, 0x041F,
0x0440, 0x0420,
0x0441, 0x0421,
0x0442, 0x0422,
0x0443, 0x0423,
0x0444, 0x0424,
0x0445, 0x0425,
0x0446, 0x0426,
0x0447, 0x0427,
0x0448, 0x0428,
0x0449, 0x0429,
0x044A, 0x042A,
0x044B, 0x042B,
0x044C, 0x042C,
0x044D, 0x042D,
0x044E, 0x042E,
0x044F, 0x042F,
0x0451, 0x0401,
0x0452, 0x0402,
0x0453, 0x0403,
0x0454, 0x0404,
0x0455, 0x0405,
0x0456, 0x0406,
0x0457, 0x0407,
0x0458, 0x0408,
0x0459, 0x0409,
0x045A, 0x040A,
0x045B, 0x040B,
0x045C, 0x040C,
0x045E, 0x040E,
0x045F, 0x040F,
0x0461, 0x0460,
0x0463, 0x0462,
0x0465, 0x0464,
0x0467, 0x0466,
0x0469, 0x0468,
0x046B, 0x046A,
0x046D, 0x046C,
0x046F, 0x046E,
0x0471, 0x0470,
0x0473, 0x0472,
0x0475, 0x0474,
0x0477, 0x0476,
0x0479, 0x0478,
0x047B, 0x047A,
0x047D, 0x047C,
0x047F, 0x047E,
0x0481, 0x0480,
0x0491, 0x0490,
0x0493, 0x0492,
0x0495, 0x0494,
0x0497, 0x0496,
0x0499, 0x0498,
0x049B, 0x049A,
0x049D, 0x049C,
0x049F, 0x049E,
0x04A1, 0x04A0,
0x04A3, 0x04A2,
0x04A5, 0x04A4,
0x04A7, 0x04A6,
0x04A9, 0x04A8,
0x04AB, 0x04AA,
0x04AD, 0x04AC,
0x04AF, 0x04AE,
0x04B1, 0x04B0,
0x04B3, 0x04B2,
0x04B5, 0x04B4,
0x04B7, 0x04B6,
0x04B9, 0x04B8,
0x04BB, 0x04BA,
0x04BD, 0x04BC,
0x04BF, 0x04BE,
0x04C2, 0x04C1,
0x04C4, 0x04C3,
0x04C8, 0x04C7,
0x04CC, 0x04CB,
0x04D1, 0x04D0,
0x04D3, 0x04D2,
0x04D5, 0x04D4,
0x04D7, 0x04D6,
0x04D9, 0x04D8,
0x04DB, 0x04DA,
0x04DD, 0x04DC,
0x04DF, 0x04DE,
0x04E1, 0x04E0,
0x04E3, 0x04E2,
0x04E5, 0x04E4,
0x04E7, 0x04E6,
0x04E9, 0x04E8,
0x04EB, 0x04EA,
0x04EF, 0x04EE,
0x04F1, 0x04F0,
0x04F3, 0x04F2,
0x04F5, 0x04F4,
0x04F9, 0x04F8,
0x0561, 0x0531,
0x0562, 0x0532,
0x0563, 0x0533,
0x0564, 0x0534,
0x0565, 0x0535,
0x0566, 0x0536,
0x0567, 0x0537,
0x0568, 0x0538,
0x0569, 0x0539,
0x056A, 0x053A,
0x056B, 0x053B,
0x056C, 0x053C,
0x056D, 0x053D,
0x056E, 0x053E,
0x056F, 0x053F,
0x0570, 0x0540,
0x0571, 0x0541,
0x0572, 0x0542,
0x0573, 0x0543,
0x0574, 0x0544,
0x0575, 0x0545,
0x0576, 0x0546,
0x0577, 0x0547,
0x0578, 0x0548,
0x0579, 0x0549,
0x057A, 0x054A,
0x057B, 0x054B,
0x057C, 0x054C,
0x057D, 0x054D,
0x057E, 0x054E,
0x057F, 0x054F,
0x0580, 0x0550,
0x0581, 0x0551,
0x0582, 0x0552,
0x0583, 0x0553,
0x0584, 0x0554,
0x0585, 0x0555,
0x0586, 0x0556,
0x10D0, 0x10A0,
0x10D1, 0x10A1,
0x10D2, 0x10A2,
0x10D3, 0x10A3,
0x10D4, 0x10A4,
0x10D5, 0x10A5,
0x10D6, 0x10A6,
0x10D7, 0x10A7,
0x10D8, 0x10A8,
0x10D9, 0x10A9,
0x10DA, 0x10AA,
0x10DB, 0x10AB,
0x10DC, 0x10AC,
0x10DD, 0x10AD,
0x10DE, 0x10AE,
0x10DF, 0x10AF,
0x10E0, 0x10B0,
0x10E1, 0x10B1,
0x10E2, 0x10B2,
0x10E3, 0x10B3,
0x10E4, 0x10B4,
0x10E5, 0x10B5,
0x10E6, 0x10B6,
0x10E7, 0x10B7,
0x10E8, 0x10B8,
0x10E9, 0x10B9,
0x10EA, 0x10BA,
0x10EB, 0x10BB,
0x10EC, 0x10BC,
0x10ED, 0x10BD,
0x10EE, 0x10BE,
0x10EF, 0x10BF,
0x10F0, 0x10C0,
0x10F1, 0x10C1,
0x10F2, 0x10C2,
0x10F3, 0x10C3,
0x10F4, 0x10C4,
0x10F5, 0x10C5,
0x1E01, 0x1E00,
0x1E03, 0x1E02,
0x1E05, 0x1E04,
0x1E07, 0x1E06,
0x1E09, 0x1E08,
0x1E0B, 0x1E0A,
0x1E0D, 0x1E0C,
0x1E0F, 0x1E0E,
0x1E11, 0x1E10,
0x1E13, 0x1E12,
0x1E15, 0x1E14,
0x1E17, 0x1E16,
0x1E19, 0x1E18,
0x1E1B, 0x1E1A,
0x1E1D, 0x1E1C,
0x1E1F, 0x1E1E,
0x1E21, 0x1E20,
0x1E23, 0x1E22,
0x1E25, 0x1E24,
0x1E27, 0x1E26,
0x1E29, 0x1E28,
0x1E2B, 0x1E2A,
0x1E2D, 0x1E2C,
0x1E2F, 0x1E2E,
0x1E31, 0x1E30,
0x1E33, 0x1E32,
0x1E35, 0x1E34,
0x1E37, 0x1E36,
0x1E39, 0x1E38,
0x1E3B, 0x1E3A,
0x1E3D, 0x1E3C,
0x1E3F, 0x1E3E,
0x1E41, 0x1E40,
0x1E43, 0x1E42,
0x1E45, 0x1E44,
0x1E47, 0x1E46,
0x1E49, 0x1E48,
0x1E4B, 0x1E4A,
0x1E4D, 0x1E4C,
0x1E4F, 0x1E4E,
0x1E51, 0x1E50,
0x1E53, 0x1E52,
0x1E55, 0x1E54,
0x1E57, 0x1E56,
0x1E59, 0x1E58,
0x1E5B, 0x1E5A,
0x1E5D, 0x1E5C,
0x1E5F, 0x1E5E,
0x1E61, 0x1E60,
0x1E63, 0x1E62,
0x1E65, 0x1E64,
0x1E67, 0x1E66,
0x1E69, 0x1E68,
0x1E6B, 0x1E6A,
0x1E6D, 0x1E6C,
0x1E6F, 0x1E6E,
0x1E71, 0x1E70,
0x1E73, 0x1E72,
0x1E75, 0x1E74,
0x1E77, 0x1E76,
0x1E79, 0x1E78,
0x1E7B, 0x1E7A,
0x1E7D, 0x1E7C,
0x1E7F, 0x1E7E,
0x1E81, 0x1E80,
0x1E83, 0x1E82,
0x1E85, 0x1E84,
0x1E87, 0x1E86,
0x1E89, 0x1E88,
0x1E8B, 0x1E8A,
0x1E8D, 0x1E8C,
0x1E8F, 0x1E8E,
0x1E91, 0x1E90,
0x1E93, 0x1E92,
0x1E95, 0x1E94,
0x1EA1, 0x1EA0,
0x1EA3, 0x1EA2,
0x1EA5, 0x1EA4,
0x1EA7, 0x1EA6,
0x1EA9, 0x1EA8,
0x1EAB, 0x1EAA,
0x1EAD, 0x1EAC,
0x1EAF, 0x1EAE,
0x1EB1, 0x1EB0,
0x1EB3, 0x1EB2,
0x1EB5, 0x1EB4,
0x1EB7, 0x1EB6,
0x1EB9, 0x1EB8,
0x1EBB, 0x1EBA,
0x1EBD, 0x1EBC,
0x1EBF, 0x1EBE,
0x1EC1, 0x1EC0,
0x1EC3, 0x1EC2,
0x1EC5, 0x1EC4,
0x1EC7, 0x1EC6,
0x1EC9, 0x1EC8,
0x1ECB, 0x1ECA,
0x1ECD, 0x1ECC,
0x1ECF, 0x1ECE,
0x1ED1, 0x1ED0,
0x1ED3, 0x1ED2,
0x1ED5, 0x1ED4,
0x1ED7, 0x1ED6,
0x1ED9, 0x1ED8,
0x1EDB, 0x1EDA,
0x1EDD, 0x1EDC,
0x1EDF, 0x1EDE,
0x1EE1, 0x1EE0,
0x1EE3, 0x1EE2,
0x1EE5, 0x1EE4,
0x1EE7, 0x1EE6,
0x1EE9, 0x1EE8,
0x1EEB, 0x1EEA,
0x1EED, 0x1EEC,
0x1EEF, 0x1EEE,
0x1EF1, 0x1EF0,
0x1EF3, 0x1EF2,
0x1EF5, 0x1EF4,
0x1EF7, 0x1EF6,
0x1EF9, 0x1EF8,
0x1F00, 0x1F08,
0x1F01, 0x1F09,
0x1F02, 0x1F0A,
0x1F03, 0x1F0B,
0x1F04, 0x1F0C,
0x1F05, 0x1F0D,
0x1F06, 0x1F0E,
0x1F07, 0x1F0F,
0x1F10, 0x1F18,
0x1F11, 0x1F19,
0x1F12, 0x1F1A,
0x1F13, 0x1F1B,
0x1F14, 0x1F1C,
0x1F15, 0x1F1D,
0x1F20, 0x1F28,
0x1F21, 0x1F29,
0x1F22, 0x1F2A,
0x1F23, 0x1F2B,
0x1F24, 0x1F2C,
0x1F25, 0x1F2D,
0x1F26, 0x1F2E,
0x1F27, 0x1F2F,
0x1F30, 0x1F38,
0x1F31, 0x1F39,
0x1F32, 0x1F3A,
0x1F33, 0x1F3B,
0x1F34, 0x1F3C,
0x1F35, 0x1F3D,
0x1F36, 0x1F3E,
0x1F37, 0x1F3F,
0x1F40, 0x1F48,
0x1F41, 0x1F49,
0x1F42, 0x1F4A,
0x1F43, 0x1F4B,
0x1F44, 0x1F4C,
0x1F45, 0x1F4D,
0x1F51, 0x1F59,
0x1F53, 0x1F5B,
0x1F55, 0x1F5D,
0x1F57, 0x1F5F,
0x1F60, 0x1F68,
0x1F61, 0x1F69,
0x1F62, 0x1F6A,
0x1F63, 0x1F6B,
0x1F64, 0x1F6C,
0x1F65, 0x1F6D,
0x1F66, 0x1F6E,
0x1F67, 0x1F6F,
0x1F80, 0x1F88,
0x1F81, 0x1F89,
0x1F82, 0x1F8A,
0x1F83, 0x1F8B,
0x1F84, 0x1F8C,
0x1F85, 0x1F8D,
0x1F86, 0x1F8E,
0x1F87, 0x1F8F,
0x1F90, 0x1F98,
0x1F91, 0x1F99,
0x1F92, 0x1F9A,
0x1F93, 0x1F9B,
0x1F94, 0x1F9C,
0x1F95, 0x1F9D,
0x1F96, 0x1F9E,
0x1F97, 0x1F9F,
0x1FA0, 0x1FA8,
0x1FA1, 0x1FA9,
0x1FA2, 0x1FAA,
0x1FA3, 0x1FAB,
0x1FA4, 0x1FAC,
0x1FA5, 0x1FAD,
0x1FA6, 0x1FAE,
0x1FA7, 0x1FAF,
0x1FB0, 0x1FB8,
0x1FB1, 0x1FB9,
0x1FD0, 0x1FD8,
0x1FD1, 0x1FD9,
0x1FE0, 0x1FE8,
0x1FE1, 0x1FE9,
0x24D0, 0x24B6,
0x24D1, 0x24B7,
0x24D2, 0x24B8,
0x24D3, 0x24B9,
0x24D4, 0x24BA,
0x24D5, 0x24BB,
0x24D6, 0x24BC,
0x24D7, 0x24BD,
0x24D8, 0x24BE,
0x24D9, 0x24BF,
0x24DA, 0x24C0,
0x24DB, 0x24C1,
0x24DC, 0x24C2,
0x24DD, 0x24C3,
0x24DE, 0x24C4,
0x24DF, 0x24C5,
0x24E0, 0x24C6,
0x24E1, 0x24C7,
0x24E2, 0x24C8,
0x24E3, 0x24C9,
0x24E4, 0x24CA,
0x24E5, 0x24CB,
0x24E6, 0x24CC,
0x24E7, 0x24CD,
0x24E8, 0x24CE,
0x24E9, 0x24CF,
0xFF41, 0xFF21,
0xFF42, 0xFF22,
0xFF43, 0xFF23,
0xFF44, 0xFF24,
0xFF45, 0xFF25,
0xFF46, 0xFF26,
0xFF47, 0xFF27,
0xFF48, 0xFF28,
0xFF49, 0xFF29,
0xFF4A, 0xFF2A,
0xFF4B, 0xFF2B,
0xFF4C, 0xFF2C,
0xFF4D, 0xFF2D,
0xFF4E, 0xFF2E,
0xFF4F, 0xFF2F,
0xFF50, 0xFF30,
0xFF51, 0xFF31,
0xFF52, 0xFF32,
0xFF53, 0xFF33,
0xFF54, 0xFF34,
0xFF55, 0xFF35,
0xFF56, 0xFF36,
0xFF57, 0xFF37,
0xFF58, 0xFF38,
0xFF59, 0xFF39,
0xFF5A, 0xFF3A
};
const unsigned NMAX = FB_NELEM(table) / 2;
} // anonymous namespace
unsigned short unicodeUpper(unsigned short c)
{
unsigned highBound = NMAX, lowBound = 0;
while (highBound > lowBound)
{
const unsigned temp = (highBound + lowBound) >> 1;
if (table[temp << 1] < c)
lowBound = temp + 1;
else
highBound = temp;
}
if (lowBound != NMAX && table[lowBound << 1] == c)
return table[(lowBound << 1) + 1];
return c;
}

View File

@ -1,27 +0,0 @@
/*
* PROGRAM: Firebird generic routine
* MODULE: unicodeUpper.h
* DESCRIPTION: Converts unicode character to uppercase.
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2015 Alex Peshkov <peshkoff at mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
unsigned short unicodeUpper(unsigned short c);

View File

@ -38,6 +38,7 @@
#endif
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include "../common/gdsassert.h"
#include "../common/utils_proto.h"
@ -1604,4 +1605,34 @@ const ISC_STATUS* const origen = v;
return false;
}
const char* dpbItemUpper(const char* s, FB_SIZE_T l, Firebird::string& buf)
{
if (l && (s[0] == '"' || s[0] == '\''))
{
const char end_quote = s[0];
// quoted string - strip quotes
for (FB_SIZE_T i = 1; i < l; ++i)
{
if (s[i] == end_quote)
{
if (++i >= l || s[i] != end_quote)
break; // delimited quote, done processing
// skiped the escape quote, continue processing
}
buf += s[i];
}
return buf.c_str();
}
// non-quoted string - try to uppercase
for (FB_SIZE_T i = 0; i < l; ++i)
{
if (!(s[i] & 0x80))
buf += toupper(s[i]);
else
return NULL; // contains non-ascii data
}
return buf.c_str();
}
} // namespace fb_utils

View File

@ -190,6 +190,19 @@ namespace fb_utils
// Check does vector contain particular code or not
bool containsErrorCode(const ISC_STATUS* v, ISC_STATUS code);
// Uppercase/strip string according to login rules
const char* dpbItemUpper(const char* s, FB_SIZE_T l, Firebird::string& buf);
// Uppercase/strip string according to login rules
template <typename STR>
void dpbItemUpper(STR& name)
{
Firebird::string buf;
const char* up = dpbItemUpper(name.c_str(), name.length(), buf);
if (up)
name = up;
}
} // namespace fb_utils
#endif // INCLUDE_UTILS_PROTO_H

View File

@ -9473,7 +9473,6 @@ bool CreateFilterNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
void CreateFilterNode::execute(thread_db* tdbb, DsqlCompilerScratch* /*dsqlScratch*/, jrd_tra* transaction)
{
MetaName ownerName(tdbb->getAttachment()->att_user->usr_user_name);
IntlUtil::toUpper(ownerName);
// run all statements under savepoint control
AutoSavePoint savePoint(tdbb, transaction);
@ -9697,7 +9696,6 @@ bool CreateRoleNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
void CreateRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
{
MetaName ownerName(tdbb->getAttachment()->att_user->usr_user_name);
IntlUtil::toUpper(ownerName);
// run all statements under savepoint control
AutoSavePoint savePoint(tdbb, transaction);
@ -10201,7 +10199,6 @@ bool DropRoleNode::checkPermission(thread_db* tdbb, jrd_tra* transaction)
void DropRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction)
{
MetaName user(tdbb->getAttachment()->att_user->usr_user_name);
IntlUtil::toUpper(user);
// run all statements under savepoint control
AutoSavePoint savePoint(tdbb, transaction);
@ -10261,9 +10258,7 @@ void DropRoleNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jr
Firebird::MetaName UserNode::upper(const Firebird::MetaName& str)
{
Firebird::MetaName tmp(str);
IntlUtil::toUpper(tmp);
return tmp;
return str;
}
@ -10335,7 +10330,6 @@ void CreateAlterUserNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
(Arg::Gds(isc_random) << "Missing user name for ALTER CURRENT USER").raise();
text = usr->usr_user_name;
IntlUtil::toUpper(text);
}
Firebird::LocalStatus s;
@ -10655,12 +10649,10 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
else
{
userType = obj_user;
IntlUtil::toUpper(user);
}
break;
case obj_user:
IntlUtil::toUpper(user);
break;
case obj_sql_role:
@ -10704,8 +10696,6 @@ void GrantRevokeNode::grantRevoke(thread_db* tdbb, jrd_tra* transaction, const G
if (grantor && !tdbb->getAttachment()->locksmith())
status_exception::raise(Arg::PrivateDyn(252) << SYSDBA_USER_NAME);
IntlUtil::toUpper(grantorRevoker);
if (!isGrant && !privs) // REVOKE ALL ON ALL
{
AutoCacheRequest request(tdbb, drq_e_grant3, DYN_REQUESTS);

View File

@ -68,6 +68,10 @@
#include <unistd.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
// Globals
GpreGlobals gpreGlob;
@ -247,6 +251,11 @@ const UCHAR CHR_DBLQUOTE = 64;
int main(int argc, char* argv[])
{
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
gpre_sym* symbol;
// CVC: COUNT + 1 because IN_SW_GPRE_INTERP is repeated in gpre_in_sw_table.
sw_tab_t sw_table[IN_SW_GPRE_COUNT + 1];

View File

@ -62,6 +62,7 @@
#include "../common/classes/FpeControl.h"
#include "../common/os/path_utils.h"
#include "../common/StatusHolder.h"
#include "../common/Tokens.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@ -166,7 +167,6 @@ const int MAX_TERMS = 10; // max # of terms in an interactive cmd
const char* ISQL_COUNTERS_SET = "CurrentMemory, MaxMemory, RealTime, UserTime, Buffers, Reads, Writes, Fetches";
const int ISQL_COUNTERS = 8;
namespace IcuUtil
{
// Duplicate from ICU to not need to link ISQL with it. It's used by U8_NEXT_UNSAFE.
@ -342,8 +342,6 @@ static bool check_time(const tm& times);
static bool check_timestamp(const tm& times, const int msec);
static size_t chop_at(char target[], const size_t size);
static void col_check(const TEXT*, unsigned*);
static void copy_str(Firebird::string&, const TEXT**, bool*, const TEXT* const,
const TEXT* const, literal_string_type);
static processing_state copy_table(TEXT*, TEXT*, TEXT*);
static processing_state create_db(const TEXT*, TEXT*);
static void do_isql();
@ -362,8 +360,6 @@ static processing_state get_dialect(const char* const dialect_str,
char* const bad_dialect_buf, bool& bad_dialect);
static processing_state get_statement(TEXT* const, const size_t, const TEXT*);
static bool get_numeric(const UCHAR*, USHORT, SSHORT*, SINT64*);
static void get_str(const TEXT* const, const TEXT**, const TEXT**,
literal_string_type*);
static void print_set(const char* str, bool v);
static processing_state print_sets();
static processing_state help(const TEXT*);
@ -3464,106 +3460,6 @@ static void col_check(const TEXT* tabname, unsigned* colnumber)
}
static void copy_str(Firebird::string& output_str,
const TEXT** input_str,
bool* done,
const TEXT* const str_begin,
const TEXT* const str_end,
literal_string_type str_flag)
{
/**************************************
*
* c o p y _ s t r
*
**************************************
*
* Functional description
*
* Copy and/or modify the data in the input buffer and stores it
* into output buffer.
*
* For SINGLE_QUOTED_STRING, copy everything from the begining of the
* the input buffer to the end of the string constant
*
* For DOUBLE_QUOTED_STRING, copy everything from the begining of the
* the input buffer to the begining of the string constant
*
* a. replace double quote string delimited character with single
* quote
* b. if '""' is found with in the string constant, removes one
* extra double quote
* c. if a single quote is found with in the string constant,
* adds one more single quote
* d. replace ending double quote string delimited character with
* single quote
*
* For NO_MORE_STRING, copy everything from the begining of the
* the input buffer to the end of input buffer
*
* Input Arguments:
*
* 1. address of the output buffer
* 2. address of the input buffer
* 3. address of the end of processing flag
*
* Output Arguments:
*
* 1. pointer to begining of the string constant
* 2. pointer to ending of the string constant
* 3. string type
*
**************************************/
int slen = 0;
const TEXT* b1;
const TEXT* temp_local_stmt_str = *input_str;
switch (str_flag)
{
case SINGLE_QUOTED_STRING:
slen = str_end - temp_local_stmt_str;
output_str.append(temp_local_stmt_str, slen);
*input_str = str_end;
break;
case DOUBLE_QUOTED_STRING:
slen = str_begin - temp_local_stmt_str;
output_str.append(temp_local_stmt_str, slen);
output_str += SINGLE_QUOTE;
b1 = str_begin + 1;
while (b1 < str_end)
{
output_str += *b1;
switch (*b1)
{
case SINGLE_QUOTE:
output_str += SINGLE_QUOTE;
break;
case DBL_QUOTE:
b1++;
if (*b1 != DBL_QUOTE)
{
output_str[output_str.length() - 1] = SINGLE_QUOTE;
b1--;
}
break;
default:
break;
}
b1++;
}
*input_str = b1;
break;
case NO_MORE_STRING:
output_str += temp_local_stmt_str;
*done = true;
*input_str = temp_local_stmt_str + strlen(temp_local_stmt_str);
break;
default:
break;
}
}
static processing_state copy_table(TEXT* source,
TEXT* destination,
TEXT* otherdb)
@ -3674,13 +3570,17 @@ static processing_state copy_table(TEXT* source,
}
static void appendClause(Firebird::string& to, const char* label, const TEXT* value)
static void appendClause(Firebird::string& to, const char* label, const TEXT* value, char quote = 0)
{
to += ' ';
to += label;
to += " \'";
to += ' ';
if (quote)
to += quote;
to += value;
to += "\' ";
if (quote)
to += quote;
to += ' ';
}
@ -3708,6 +3608,48 @@ static processing_state create_db(const TEXT* statement, TEXT* d_name)
// Disconnect from the database and cleanup
ISQL_disconnect_database(false);
// Parse statement to tokens
const char* quotes = isqlGlob.SQL_dialect == 1 ? "\"'" : "'";
Firebird::string nlStatement(statement);
nlStatement += '\n';
Firebird::Tokens toks(0, nlStatement.c_str(), Firebird::sqlSpaces, quotes, Firebird::sqlComments);
const unsigned KEY_USER = 0;
const unsigned KEY_PASS = 1;
const unsigned KEY_ROLE = 2;
const unsigned KEY_NAMES = 3;
const unsigned KEY_SET = 4;
struct Key {
const char* text;
bool has;
};
Key keys[5] = {
{ "USER", false },
{ "PASSWORD", false },
{ "ROLE", false },
{ "NAMES", false },
{ "SET", false }
};
for (unsigned t = 0; t < toks.getCount(); ++t)
{
Firebird::NoCaseString token(toks[t].text, toks[t].length);
unsigned k;
for (k = 0; k < FB_NELEM(keys); ++k)
{
if (token == keys[k].text)
{
if (k != KEY_NAMES || keys[KEY_SET].has)
keys[k].has = true;
break;
}
}
if (k != KEY_SET)
keys[KEY_SET].has = false;
}
for (int createWithoutRole = 0; createWithoutRole < 2; ++createWithoutRole)
{
ret = SKIP;
@ -3715,117 +3657,38 @@ static processing_state create_db(const TEXT* statement, TEXT* d_name)
TEXT psw[PASSWORD_LENGTH];
TEXT role[ROLE_LENGTH];
Firebird::string local_statement(statement);
Firebird::string modifiedCreateStatement(statement);
TEXT quote = DBL_QUOTE;
const TEXT* p = NULL;
// If there is a user parameter, we will set it into the create stmt.
if (global_usr || global_psw ||
// If there is a global parameter, we will set it into the create stmt.
if (global_usr || global_role || global_psw ||
(*setValues.ISQL_charset && strcmp(setValues.ISQL_charset, DEFCHARSET)))
{
strip_quotes(isqlGlob.User, usr);
strcpy(usr, isqlGlob.User);
strip_quotes(Password, psw);
strip_quotes(isqlGlob.Role, role);
// Look for the quotes on the database name and find the close quotes.
// Use '"' first, if not successful try '''.
// CVC: Again, this is wrong with embedded quotes.
// Maybe IUTILS_remove_and_unescape_quotes coupled with IUTILS_copy_SQL_id could work.
const TEXT* q = strchr(statement, quote);
if (!q)
strcpy(role, isqlGlob.Role);
Firebird::string clauses;
if (global_usr && !keys[KEY_USER].has)
appendClause(clauses, keys[KEY_USER].text, usr);
if (global_psw && !keys[KEY_PASS].has)
appendClause(clauses, keys[KEY_PASS].text, psw, SINGLE_QUOTE);
if (global_role && (!keys[KEY_ROLE].has) && createWithoutRole == 0)
appendClause(clauses, keys[KEY_ROLE].text, role);
if (*setValues.ISQL_charset && strcmp(setValues.ISQL_charset, DEFCHARSET)&& !keys[KEY_NAMES].has)
{
quote = SINGLE_QUOTE;
q = strchr(statement, quote);
Firebird::string setNames = keys[KEY_SET].text;
setNames += ' ';
setNames += keys[KEY_NAMES].text;
appendClause(clauses, setNames.c_str(), setValues.ISQL_charset, SINGLE_QUOTE);
}
if (q)
{
// Set quote to match open quote
quote = *q;
q++;
p = strchr(q, quote);
if (p)
{
p++;
const ptrdiff_t slen = p - statement;
local_statement.resize(slen);
if (isqlGlob.SQL_dialect == 1)
{
if (global_usr)
appendClause(local_statement, "USER", usr);
if (global_psw)
appendClause(local_statement, "PASSWORD", psw);
if (global_role && createWithoutRole == 0)
appendClause(local_statement, "ROLE", role);
if (*setValues.ISQL_charset && strcmp(setValues.ISQL_charset, DEFCHARSET))
appendClause(local_statement, "SET NAMES", setValues.ISQL_charset);
local_statement += p;
}
}
}
}
SLONG cnt = 0;
if ((isqlGlob.SQL_dialect == 0) || (isqlGlob.SQL_dialect > 1))
{
const TEXT* q = strchr(statement, SINGLE_QUOTE);
while (q)
{
cnt++;
const TEXT* l = q + 1;
q = strchr(l, SINGLE_QUOTE);
}
Firebird::string new_local_statement;
TEXT errbuf[MSG_LENGTH];
const TEXT* temp_local_stmt_str = local_statement.c_str();
bool done = false;
while (!done)
{
const TEXT* str_begin = NULL;
const TEXT* str_end = NULL;
literal_string_type str_flag = INIT_STR_FLAG;
get_str(temp_local_stmt_str, &str_begin, &str_end, &str_flag);
if (str_flag == INCOMPLETE_STRING)
{
IUTILS_msg_get(INCOMPLETE_STR, errbuf, SafeArg() << "create database statement");
STDERROUT(errbuf);
return (FAIL);
}
copy_str(new_local_statement, &temp_local_stmt_str, &done, str_begin, str_end, str_flag);
}
if (global_usr)
appendClause(new_local_statement, "USER", usr);
if (global_psw)
appendClause(new_local_statement, "PASSWORD", psw);
if (global_role && createWithoutRole == 0)
appendClause(new_local_statement, "ROLE", role);
if (*setValues.ISQL_charset && strcmp(setValues.ISQL_charset, DEFCHARSET))
appendClause(new_local_statement, "SET NAMES", setValues.ISQL_charset);
if (p && strlen(p) > 0)
{
temp_local_stmt_str = p;
bool done2 = false;
while (!done2)
{
const TEXT* str_begin = NULL;
const TEXT* str_end = NULL;
literal_string_type str_flag = INIT_STR_FLAG;
get_str(temp_local_stmt_str, &str_begin, &str_end, &str_flag);
if (str_flag == INCOMPLETE_STRING)
{
IUTILS_msg_get(INCOMPLETE_STR, errbuf, SafeArg() << "create database statement");
STDERROUT(errbuf);
return (FAIL);
}
copy_str(new_local_statement, &temp_local_stmt_str, &done2, str_begin, str_end, str_flag);
}
}
local_statement = new_local_statement;
if (toks.getCount() > 3)
modifiedCreateStatement.insert(toks[3].origin, clauses);
else
modifiedCreateStatement += clauses;
}
// execute the create statement
@ -3834,8 +3697,8 @@ static processing_state create_db(const TEXT* statement, TEXT* d_name)
unsigned dialect =
(isqlGlob.SQL_dialect == 0 || isqlGlob.SQL_dialect == SQL_DIALECT_V6_TRANSITION) ?
requested_SQL_dialect : isqlGlob.SQL_dialect;
DB = Firebird::UtilInterfacePtr()->executeCreateDatabase(fbStatus, local_statement.length(),
local_statement.c_str(), dialect, NULL);
DB = Firebird::UtilInterfacePtr()->executeCreateDatabase(fbStatus, modifiedCreateStatement.length(),
modifiedCreateStatement.c_str(), dialect, NULL);
if ((!DB) && (createWithoutRole == 0) && (fbStatus->getErrors()[1] == isc_dsql_error))
{
@ -3863,109 +3726,12 @@ static processing_state create_db(const TEXT* statement, TEXT* d_name)
// CVC: Someone may decide to play strange games with undocumented ability
// to write crap between CREATE DATABASE and the db name, as described by
// Helen on CORE-932. Let's see if we can discover the real db name.
size_t db_name_len = MAXPATHLEN - 1;
char temp_name[MAXPATHLEN];
if (!strncmp(d_name, "/*", 2) || !strncmp(d_name, "--", 2))
{
const char* target = d_name[0] == '/' ? "/*" : "--";
const char* comment = strstr(statement, target);
while (true)
{
if (target[0] == '/')
{
// We don't accept recursive comment blocks, so looking for the next *./ is safe.
comment = strstr(comment + 2, "*/");
// What happens if the comment is not closed or quotes are spoiling the party?
// Then the statement is ill-formed and will be rejected by the server anyway.
if (comment)
{
comment += 2;
while (*comment && fb_isspace(*comment))
++comment;
}
else
break; // no end of block comment, error, do nothing.
}
else
{
while (!strncmp(comment, "--", 2))
{
while (*comment && *comment != '\n')
++comment;
if (*comment == '\n')
++comment; // skip the newline
while (*comment && fb_isspace(*comment))
++comment;
}
}
if (!strncmp(comment, "/*", 2))
{
target = "/*";
continue;
}
if (!strncmp(comment, "--", 2))
{
target = "--";
continue;
}
// Does the advanced user want a charset specification before the name, too?
// AFAIK, supported by IB and FB but dsql/preparse.cpp doesn't understand it.
/*
if (*comment == '_')
{
while (*comment && !fb_isspace(*comment) && *comment != '"' && *comment != '\'')
++comment;
while (*comment && fb_isspace(*comment))
++comment;
// Include the "continue" loops here for this to work in all cases.
// Check that this happens only once, etc.
}
*/
if (*comment == '"' || *comment == '\'')
{
for (const char& newquote = *comment++; *comment; ++comment)
{
if (*comment != newquote)
continue;
// If we find 'hello ''world''' this is valid.
if (comment[1] == newquote)
{
comment += 2;
if (!*comment)
break;
}
if (*comment == newquote && comment[1] != newquote)
{
db_name_len = comment - &newquote + 1;
if (db_name_len >= MAXPATHLEN)
db_name_len = MAXPATHLEN - 1;
d_name = temp_name;
fb_utils::copy_terminate(d_name, &newquote, db_name_len + 1);
break;
}
}
}
break;
} // while (true)
}
chop_at(d_name, db_name_len + 1);
strip_quotes(d_name, isqlGlob.global_Db_name);
Firebird::string s;
if (toks.getCount() > 2)
s.assign(toks[2].text, toks[2].length);
else
s = d_name;
strip_quotes(s.c_str(), isqlGlob.global_Db_name);
ISQL_get_version(true);
@ -5594,104 +5360,6 @@ static processing_state get_statement(TEXT* const statement,
}
static void get_str(const TEXT* const input_str,
const TEXT** str_begin,
const TEXT** str_end,
literal_string_type* str_flag)
{
/**************************************
*
* g e t _ s t r
*
**************************************
*
* Functional description
*
* Scanning a string constant from the input buffer. If it found, then
* passes back the starting address and ending address of the string
* constant. It also marks the type of string constant and passes back.
*
* string type:
*
* 1. SINGLE_QUOTED_STRING --- string constant delimited by
* single quotes
* 2. DOUBLE_QUOTED_STRING --- string constant delimited by
* double quotes
* 3. NO_MORE_STRING --- no string constant was found
*
* 4. INCOMPLETE_STRING --- no matching ending quote
*
* Input Arguments:
*
* 1. input buffer
*
* Output Arguments:
*
* 1. pointer to the input buffer
* 2. address to the begining of a string constant
* 3. address to the ending of a string constant
* 4. address to the string flag
*
**************************************/
const TEXT* b1 = strchr(input_str, SINGLE_QUOTE);
const TEXT* b2 = strchr(input_str, DBL_QUOTE);
if (!b1 && !b2)
*str_flag = NO_MORE_STRING;
else
{
if (b1 && !b2)
*str_flag = SINGLE_QUOTED_STRING;
else if (!b1 && b2)
{
*str_flag = DOUBLE_QUOTED_STRING;
b1 = b2;
}
else if (b1 > b2)
{
*str_flag = DOUBLE_QUOTED_STRING;
b1 = b2;
}
else
*str_flag = SINGLE_QUOTED_STRING;
*str_begin = b1;
TEXT delimited_char = *b1;
b1++;
bool done = false;
while (!done)
{
if (*b1 == delimited_char)
{
b1++;
if (*b1 == delimited_char)
b1++;
else
{
done = true;
*str_end = b1;
}
}
else
b1 = strchr(b1, delimited_char);
/* In case there is no matching ending quote (single or double)
either because of mismatched quotes or simply because user
didn't complete the quotes, we cannot find a valid string
at all. So we return a special value INCOMPLETE_STRING.
In this case str_end is not populated and hence copy_str
should not be called after get_str, but instead the caller
must process this error & return to it's calling routine
- Shailesh */
if (b1 == NULL)
{
*str_flag = INCOMPLETE_STRING;
done = true;
}
}
}
}
void ISQL_get_version(bool call_by_create_db)
{
/**************************************
@ -6267,32 +5935,19 @@ static processing_state newdb(TEXT* dbname,
// Strip quotes if well-intentioned
strip_quotes(dbname, isqlGlob.global_Db_name);
strip_quotes(usr, local_usr);
if (usr)
strcpy(local_usr, usr);
strip_quotes(psw, local_psw);
// if local user is not specified, see if global options are
// specified - don't let a global role setting carry forward if a
// specific local user was specified
//
// Special handling for SQL Roles:
// V5 client -- strip the quotes
// V6 client -- pass the role name as it is
if (sql_role_nm)
{
if (isqlGlob.SQL_dialect == SQL_DIALECT_V5)
strip_quotes(sql_role_nm, local_sql_role);
else
strcpy(local_sql_role, sql_role_nm);
}
strcpy(local_sql_role, sql_role_nm);
if (!(strlen(local_sql_role)) && global_role)
{
if (isqlGlob.SQL_dialect == SQL_DIALECT_V5)
strip_quotes(isqlGlob.Role, local_sql_role);
else
strcpy(local_sql_role, isqlGlob.Role);
}
strcpy(local_sql_role, isqlGlob.Role);
if (!(strlen(local_usr)) && global_usr)
strcpy(local_usr, isqlGlob.User);

View File

@ -58,7 +58,6 @@
#include "../jrd/IntlManager.h"
#include "../jrd/PreparedStatement.h"
#include "../jrd/constants.h"
#include "../common/IntlUtil.h"
using namespace Firebird;
using namespace Jrd;
@ -226,7 +225,7 @@ static const trigger_msg trigger_messages[] =
void INI_format(const MetaName& owner, const MetaName& charset)
void INI_format(const char* owner, const char* charset)
{
/**************************************
*
@ -243,15 +242,13 @@ void INI_format(const MetaName& owner, const MetaName& charset)
thread_db* tdbb = JRD_get_thread_data();
Jrd::Attachment* attachment = tdbb->getAttachment();
fb_assert(owner.hasData());
fb_assert(owner && owner[0]);
// Uppercase owner name
MetaName ownerName(owner);
IntlUtil::toUpper(ownerName);
// Uppercase charset name
MetaName rdbCharSetName(charset.hasData() ? charset.c_str() : DEFAULT_DB_CHARACTER_SET_NAME);
IntlUtil::toUpper(rdbCharSetName);
MetaName rdbCharSetName(charset && charset[0] ? charset : DEFAULT_DB_CHARACTER_SET_NAME);
const int* fld;

View File

@ -29,7 +29,7 @@ namespace Jrd {
class dsql_dbb;
}
void INI_format(const Firebird::MetaName&, const Firebird::MetaName&);
void INI_format(const char*, const char*);
USHORT INI_get_trig_flags(const TEXT*);
void INI_init(Jrd::thread_db*);
void INI_init2(Jrd::thread_db*);

View File

@ -1022,7 +1022,6 @@ static void start_transaction(thread_db* tdbb, bool transliterate, jrd_tra** tr
Jrd::Attachment* attachment, unsigned int tpb_length, const UCHAR* tpb);
static void release_attachment(thread_db*, Jrd::Attachment*);
static void rollback(thread_db*, jrd_tra*, const bool);
static void strip_quotes(string&);
static void purge_attachment(thread_db* tdbb, StableAttachmentPart* sAtt, unsigned flags = 0);
static void getUserInfo(UserId&, const DatabaseOptions&, const char*, const char*,
const RefPtr<Config>*, bool, ICryptKeyCallback*);
@ -1297,38 +1296,15 @@ void JRD_make_role_name(string& userIdRole, const int dialect)
switch (dialect)
{
case SQL_DIALECT_V5:
strip_quotes(userIdRole);
IntlUtil::toUpper(userIdRole);
// Invoke utility twice: first to strip quotes, next to uppercase if needed
// For unquoted string nothing bad happens
fb_utils::dpbItemUpper(userIdRole);
fb_utils::dpbItemUpper(userIdRole);
break;
case SQL_DIALECT_V6_TRANSITION:
case SQL_DIALECT_V6:
if (userIdRole.hasData() && (userIdRole[0] == DBL_QUOTE || userIdRole[0] == SINGLE_QUOTE))
{
const char end_quote = userIdRole[0];
// remove the delimited quotes and escape quote
// from ROLE name
userIdRole.erase(0, 1);
for (string::iterator p = userIdRole.begin(); p < userIdRole.end(); ++p)
{
if (*p == end_quote)
{
if (++p < userIdRole.end() && *p == end_quote)
{
// skip the escape quote here
userIdRole.erase(p--);
}
else
{
// delimited done
userIdRole.erase(--p, userIdRole.end());
}
}
}
}
else
IntlUtil::toUpper(userIdRole);
fb_utils::dpbItemUpper(userIdRole);
break;
default:
@ -2694,7 +2670,9 @@ JAttachment* JProvider::createDatabase(CheckStatusWrapper* user_status, const ch
if (options.dpb_set_no_reserve)
PAG_set_no_reserve(tdbb, options.dpb_no_reserve);
INI_format(attachment->att_user->usr_user_name.c_str(), options.dpb_set_db_charset.c_str());
string dpb_set_db_charset(options.dpb_set_db_charset);
fb_utils::dpbItemUpper(dpb_set_db_charset);
INI_format(attachment->att_user->usr_user_name.c_str(), dpb_set_db_charset.c_str());
// If we have not allocated first TIP page, do it now.
if (!dbb->dbb_t_pages || !dbb->dbb_t_pages->count())
@ -5636,6 +5614,7 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
dpb_overwrite = false;
dpb_sql_dialect = 99;
invalid_client_SQL_dialect = false;
dpb_utf8_filename = false;
if (dpb_length == 0)
{
@ -5649,12 +5628,14 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli
ClumpletReader rdr(ClumpletReader::dpbList, dpb, dpb_length, dpbErrorRaise);
dumpAuthBlock("DatabaseOptions::get()", &rdr, isc_dpb_auth_block);
dpb_utf8_filename = rdr.find(isc_dpb_utf8_filename);
for (rdr.rewind(); !rdr.isEof(); rdr.moveNext())
{
switch (rdr.getClumpTag())
{
case isc_dpb_utf8_filename:
dpb_utf8_filename = true;
break;
case isc_dpb_working_directory:
getPath(rdr, dpb_working_directory);
break;
@ -6648,39 +6629,6 @@ bool JRD_shutdown_database(Database* dbb, const unsigned flags)
}
static void strip_quotes(string& out)
{
/**************************************
*
* s t r i p _ q u o t e s
*
**************************************
*
* Functional description
* Get rid of quotes around strings
* Quotes in the middle will confuse this routine!
*
**************************************/
if (out.isEmpty())
{
return;
}
if (out[0] == DBL_QUOTE || out[0] == SINGLE_QUOTE)
{
// Skip any initial quote
const char quote = out[0];
out.erase(0, 1);
// Search for same quote
FB_SIZE_T pos = out.find(quote);
if (pos != string::npos)
{
out.erase(pos);
}
}
}
void JRD_enum_attachments(PathNameList* dbList, ULONG& atts, ULONG& dbs, ULONG& svcs)
{
/**************************************
@ -7147,6 +7095,7 @@ static void getUserInfo(UserId& user, const DatabaseOptions& options,
if (fb_utils::bootBuild())
{
auth_method = "bootBuild";
wheel = true;
}
else
@ -7155,17 +7104,17 @@ static void getUserInfo(UserId& user, const DatabaseOptions& options,
if (options.dpb_trusted_login.hasData())
{
name = options.dpb_trusted_login;
fb_utils::dpbItemUpper(name);
}
else if (options.dpb_user_name.hasData())
{
name = options.dpb_user_name;
fb_utils::dpbItemUpper(name);
}
else if (options.dpb_auth_block.hasData())
{
mapUser(name, trusted_role, &auth_method, &user.usr_auth_block, options.dpb_auth_block,
aliasName, dbName, (config ? (*config)->getSecurityDatabase() : NULL), cryptCb);
ISC_systemToUtf8(name);
ISC_systemToUtf8(trusted_role);
if (creating && config) // when config is NULL we are in error handler
{
@ -7185,8 +7134,6 @@ static void getUserInfo(UserId& user, const DatabaseOptions& options,
}
}
IntlUtil::toUpper(name);
// if the name from the user database is defined as SYSDBA,
// we define that user id as having system privileges

View File

@ -56,7 +56,6 @@
#include "../common/config/config.h"
#include "../common/os/os_utils.h"
#include "../common/classes/ClumpletWriter.h"
#include "../common/IntlUtil.h"
const int UIC_BASE = 10;
@ -1008,7 +1007,6 @@ bool SCL_role_granted(thread_db* tdbb, const UserId& usr, const TEXT* sql_role)
}
Firebird::string loginName(usr.usr_user_name);
IntlUtil::toUpper(loginName);
const TEXT* login_name = loginName.c_str();
bool found = false;
@ -1100,7 +1098,6 @@ void SCL_init(thread_db* tdbb, bool create, const UserId& tempId)
if (!create)
{
Firebird::string loginName(tempId.usr_user_name);
IntlUtil::toUpper(loginName);
const TEXT* login_name = loginName.c_str();
AutoCacheRequest request(tdbb, irq_get_role_name, IRQ_REQUESTS);
@ -1581,7 +1578,6 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
else if (user.usr_sql_role_name != user.usr_trusted_role)
{
Firebird::string loginName(user.usr_user_name);
IntlUtil::toUpper(loginName);
const TEXT* login_name = loginName.c_str();
bool roleHit = false;
AutoCacheRequest request(tdbb, irq_get_role_mem, IRQ_REQUESTS);

View File

@ -253,7 +253,7 @@ void Service::getOptions(ClumpletReader& spb)
{
case isc_spb_user_name:
spb.getString(svc_username);
svc_username.upper();
fb_utils::dpbItemUpper(svc_username);
break;
case isc_spb_sql_role_name:
@ -686,8 +686,6 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
string trusted_role;
mapUser(svc_username, trusted_role, NULL, &svc_auth_block, svc_auth_block,
"services manager", NULL, config->getSecurityDatabase(), svc_crypt_callback);
// to be changed after refsoft special roles patch!!!
trusted_role.upper();
svc_trusted_role = trusted_role == ADMIN_ROLE;
}

View File

@ -218,65 +218,9 @@ static const UCHAR trigger1[] =
blr_leave, 0,
blr_end,
blr_if,
blr_or,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 0, 0, 0, 0,
blr_or,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 3, 0, 0, 0,
blr_or,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 4, 0, 0, 0,
blr_or,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 6, 0, 0, 0,
blr_or,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 7, 0, 0, 0,
blr_or,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 8, 0, 0, 0,
blr_or,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 9, 0, 0, 0,
blr_or,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 10, 0, 0, 0,
blr_or,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 11, 0, 0, 0,
blr_eql,
blr_field, 1, 13, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R', '_', 'T', 'Y',
'P', 'E',
blr_literal, blr_long, 0, 12, 0, 0, 0,
blr_assignment,
blr_upcase,
blr_field, 1, 8, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R',
blr_field, 1, 8, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R',
blr_end,
blr_if,
blr_missing,
blr_field, 1, 11, 'R', 'D', 'B', '$', 'G', 'R', 'A', 'N', 'T', 'O', 'R',
blr_assignment,
blr_upcase,
blr_user_name,
blr_field, 1, 11, 'R', 'D', 'B', '$', 'G', 'R', 'A', 'N', 'T', 'O', 'R',
blr_end,
@ -304,7 +248,6 @@ static const UCHAR trigger1[] =
blr_eql,
blr_field, 6, 14, 'R', 'D', 'B', '$', 'O', 'W', 'N', 'E', 'R', '_', 'N',
'A', 'M', 'E',
blr_upcase,
blr_user_name,
blr_and,
blr_eql,
@ -317,11 +260,9 @@ static const UCHAR trigger1[] =
blr_field, 1, 8, 'R', 'D', 'B', '$', 'U', 'S', 'E', 'R',
blr_or,
blr_eql,
blr_upcase,
blr_user_name,
blr_literal, blr_text, 6, 0, 'S', 'Y', 'S', 'D', 'B', 'A',
blr_eql,
blr_upcase,
blr_current_role,
blr_literal, blr_text, 9, 0, 'R', 'D', 'B', '$', 'A', 'D', 'M', 'I', 'N',
blr_begin,
@ -330,7 +271,6 @@ static const UCHAR trigger1[] =
blr_neq,
blr_field, 6, 14, 'R', 'D', 'B', '$', 'O', 'W', 'N', 'E', 'R', '_', 'N',
'A', 'M', 'E',
blr_upcase,
blr_user_name,
blr_begin,
blr_if,
@ -444,11 +384,9 @@ static const UCHAR trigger1[] =
'A', 'M', 'E',
blr_and,
blr_neq,
blr_upcase,
blr_user_name,
blr_literal, blr_text, 6, 0, 'S', 'Y', 'S', 'D', 'B', 'A',
blr_neq,
blr_upcase,
blr_current_role,
blr_literal, blr_text, 9, 0, 'R', 'D', 'B', '$', 'A', 'D', 'M', 'I', 'N',
blr_begin,
@ -537,11 +475,9 @@ static const UCHAR trigger1[] =
'A', 'M', 'E',
blr_and,
blr_neq,
blr_upcase,
blr_user_name,
blr_literal, blr_text, 6, 0, 'S', 'Y', 'S', 'D', 'B', 'A',
blr_neq,
blr_upcase,
blr_current_role,
blr_literal, blr_text, 9, 0, 'R', 'D', 'B', '$', 'A', 'D', 'M', 'I', 'N',
blr_begin,
@ -695,15 +631,12 @@ static const UCHAR trigger1[] =
blr_neq,
blr_field, 18, 14, 'R', 'D', 'B', '$', 'O', 'W', 'N', 'E', 'R', '_', 'N',
'A', 'M', 'E',
blr_upcase,
blr_user_name,
blr_and,
blr_neq,
blr_upcase,
blr_user_name,
blr_literal, blr_text, 6, 0, 'S', 'Y', 'S', 'D', 'B', 'A',
blr_neq,
blr_upcase,
blr_current_role,
blr_literal, blr_text, 9, 0, 'R', 'D', 'B', '$', 'A', 'D', 'M', 'I', 'N',
blr_if,
@ -809,15 +742,12 @@ static const UCHAR trigger1[] =
blr_neq,
blr_field, 26, 14, 'R', 'D', 'B', '$', 'O', 'W', 'N', 'E', 'R', '_', 'N',
'A', 'M', 'E',
blr_upcase,
blr_user_name,
blr_and,
blr_neq,
blr_upcase,
blr_user_name,
blr_literal, blr_text, 6, 0, 'S', 'Y', 'S', 'D', 'B', 'A',
blr_neq,
blr_upcase,
blr_current_role,
blr_literal, blr_text, 9, 0, 'R', 'D', 'B', '$', 'A', 'D', 'M', 'I', 'N',
blr_if,
@ -919,15 +849,12 @@ static const UCHAR trigger1[] =
blr_neq,
blr_field, 22, 14, 'R', 'D', 'B', '$', 'O', 'W', 'N', 'E', 'R', '_', 'N',
'A', 'M', 'E',
blr_upcase,
blr_user_name,
blr_and,
blr_neq,
blr_upcase,
blr_user_name,
blr_literal, blr_text, 6, 0, 'S', 'Y', 'S', 'D', 'B', 'A',
blr_neq,
blr_upcase,
blr_current_role,
blr_literal, blr_text, 9, 0, 'R', 'D', 'B', '$', 'A', 'D', 'M', 'I', 'N',
blr_if,
@ -2455,15 +2382,12 @@ static const UCHAR trigger31[] =
blr_and,
blr_neq,
blr_field, 1, 11, 'R', 'D', 'B', '$', 'G', 'R', 'A', 'N', 'T', 'O', 'R',
blr_upcase,
blr_user_name,
blr_and,
blr_neq,
blr_upcase,
blr_user_name,
blr_literal, blr_text, 6, 0, 'S', 'Y', 'S', 'D', 'B', 'A',
blr_neq,
blr_upcase,
blr_current_role,
blr_literal, blr_text, 9, 0, 'R', 'D', 'B', '$', 'A', 'D', 'M', 'I', 'N',
blr_begin,
@ -2487,7 +2411,6 @@ static const UCHAR trigger31[] =
blr_neq,
blr_field, 3, 14, 'R', 'D', 'B', '$', 'O', 'W', 'N', 'E', 'R', '_', 'N',
'A', 'M', 'E',
blr_upcase,
blr_user_name,
blr_leave, 0,
blr_end,

View File

@ -106,6 +106,10 @@ enum lck_owner_t {
#include <fcntl.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
@ -277,6 +281,11 @@ int CLIB_ROUTINE main( int argc, char *argv[])
* to stdout.
*
**************************************/
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
OUTFILE outfile = stdout;
// Perform some special handling when run as a Firebird service. The

View File

@ -58,6 +58,10 @@
#include "../common/classes/Switches.h"
#include "../qli/qliswi.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
using MsgFormat::SafeArg;
@ -118,6 +122,11 @@ int CLIB_ROUTINE main(int argc, char** argv)
startup_file.append("/.qli_startup");
#endif
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
const TEXT* application_file = NULL;
ALLQ_init();
LEX_init();

View File

@ -6037,17 +6037,7 @@ static bool get_new_dpb(ClumpletWriter& dpb, const ParametersSet& par)
}
}
bool rc = dpb.find(par.user_name);
if (rc)
{
string login;
dpb.getString(login);
dpb.deleteClumplet();
ISC_utf8Upper(login);
dpb.insertString(par.user_name, login);
}
return rc;
return dpb.find(par.user_name);
}
@ -7456,7 +7446,7 @@ static void cleanDpb(Firebird::ClumpletWriter& dpb, const ParametersSet* tags)
ClntAuthBlock::ClntAuthBlock(const Firebird::PathName* fileName, Firebird::ClumpletReader* dpb,
const ParametersSet* tags)
: pluginList(getPool()), serverPluginList(getPool()),
userName(getPool()), password(getPool()),
cliUserName(getPool()), cliPassword(getPool()), cliOrigUserName(getPool()),
dataForPlugin(getPool()), dataFromPlugin(getPool()),
cryptKeys(getPool()), dpbConfig(getPool()),
hasCryptKey(false), plugins(IPluginManager::TYPE_AUTH_CLIENT),
@ -7508,7 +7498,7 @@ void ClntAuthBlock::extractDataFromPluginTo(Firebird::ClumpletWriter& dpb,
return;
}
if (REMOTE_legacy_auth(pluginName.c_str(), PROTOCOL_VERSION10)) // dataFromPlugin is encrypted password
if (REMOTE_legacy_auth(pluginName.c_str(), PROTOCOL_VERSION10)) // dataFromPlugin is encrypted cliPassword
{
fb_assert(tags->password_enc);
dpb.insertBytes(tags->password_enc, dataFromPlugin.begin(), dataFromPlugin.getCount());
@ -7538,22 +7528,24 @@ void ClntAuthBlock::loadClnt(Firebird::ClumpletWriter& dpb, const ParametersSet*
const UCHAR t = dpb.getClumpTag();
if (t == tags->user_name)
{
dpb.getString(userName);
makeUtfString(uft8Convert, userName);
HANDSHAKE_DEBUG(fprintf(stderr, "Cli: loadClnt: Loaded from PB user = %s\n", userName.c_str()));
dpb.getString(cliUserName);
makeUtfString(uft8Convert, cliUserName);
cliOrigUserName = cliUserName;
fb_utils::dpbItemUpper(cliUserName);
HANDSHAKE_DEBUG(fprintf(stderr, "Cli: loadClnt: Loaded from PB user = %s(was %s)\n", cliUserName.c_str(), cliOrigUserName.c_str()));
}
else if (t == tags->password)
{
dpb.getString(password);
makeUtfString(uft8Convert, password);
dpb.getString(cliPassword);
makeUtfString(uft8Convert, cliPassword);
HANDSHAKE_DEBUG(fprintf(stderr,
"Cli: loadClnt: Loaded from PB password = %s\n", password.c_str()));
"Cli: loadClnt: Loaded from PB cliPassword = %s\n", cliPassword.c_str()));
}
else if (t == tags->encrypt_key)
{
hasCryptKey = true;
HANDSHAKE_DEBUG(fprintf(stderr,
"Cli: loadClnt: PB contains crypt key - need encrypted line to pass\n"));
"Cli: loadClnt: PB contains crypt key\n"));
}
}
@ -7598,12 +7590,12 @@ void ClntAuthBlock::extractDataFromPluginTo(P_AUTH_CONT* to)
const char* ClntAuthBlock::getLogin()
{
return userName.nullStr();
return cliUserName.nullStr();
}
const char* ClntAuthBlock::getPassword()
{
return password.nullStr();
return cliPassword.nullStr();
}
const unsigned char* ClntAuthBlock::getData(unsigned int* length)

View File

@ -890,7 +890,7 @@ Firebird::PathName ClntAuthBlock::getPluginName()
}
template <typename T>
static void addMutliPartConnectParameter(const T& dataToAdd,
static void addMultiPartConnectParameter(const T& dataToAdd,
Firebird::ClumpletWriter& user_id, UCHAR param)
{
FB_SIZE_T remaining = dataToAdd.getCount();
@ -920,10 +920,10 @@ static void addMutliPartConnectParameter(const T& dataToAdd,
void ClntAuthBlock::extractDataFromPluginTo(Firebird::ClumpletWriter& user_id)
{
// Add user login name
if (userName.hasData())
if (cliOrigUserName.hasData())
{
HANDSHAKE_DEBUG(fprintf(stderr, "Cli: extractDataFromPluginTo: userName=%s\n", userName.c_str()));
user_id.insertString(CNCT_login, userName);
HANDSHAKE_DEBUG(fprintf(stderr, "Cli: extractDataFromPluginTo: cliOrigUserName=%s\n", cliOrigUserName.c_str()));
user_id.insertString(CNCT_login, cliOrigUserName);
}
// Add plugin name
@ -944,7 +944,7 @@ void ClntAuthBlock::extractDataFromPluginTo(Firebird::ClumpletWriter& user_id)
// and we have no ways to override this limit cause it can be sent to any version server.
// Therefore divide data into 254-byte parts, leaving first byte for the number of that part.
// This appears more reliable than put them in strict order.
addMutliPartConnectParameter(dataFromPlugin, user_id, CNCT_specific_data);
addMultiPartConnectParameter(dataFromPlugin, user_id, CNCT_specific_data);
// Client's wirecrypt requested level
user_id.insertInt(CNCT_client_crypt, clntConfig->getWireCrypt(WC_CLIENT));

View File

@ -694,7 +694,8 @@ class ClntAuthBlock FB_FINAL :
private:
Firebird::PathName pluginList; // To be passed to server
Firebird::PathName serverPluginList; // Received from server
Firebird::string userName, password; // Used by plugin, taken from DPB
Firebird::string cliUserName, cliPassword; // Used by plugin, taken from DPB
Firebird::string cliOrigUserName; // Original user anme, passed to server
// These two are legacy encrypted password, trusted auth data and so on - what plugin needs
Firebird::UCharBuffer dataForPlugin, dataFromPlugin;
Firebird::HalfStaticArray<InternalCryptKey*, 1> cryptKeys; // Wire crypt keys that came from plugin(s) last time

View File

@ -311,7 +311,7 @@ public:
if (aPb->find(tags->user_name))
{
aPb->getString(userName);
userName.upper();
fb_utils::dpbItemUpper(userName);
if (authPort->port_srv_auth_block->getLogin() &&
userName != authPort->port_srv_auth_block->getLogin())
{
@ -6251,7 +6251,7 @@ void SrvAuthBlock::load(Firebird::ClumpletReader& id)
if (id.find(CNCT_login))
{
id.getString(userName);
userName.upper();
fb_utils::dpbItemUpper(userName);
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: AuthBlock: login %s\n", userName.c_str()));
}

View File

@ -44,6 +44,10 @@
#include "../common/StatusArg.h"
#include "../jrd/license.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
using namespace Firebird;
// Here we define main control structure
@ -972,6 +976,11 @@ static void ctrl_c_handler(int signal)
int main(int ac, char** av)
{
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
if (ac < 2 || (ac == 2 && strcmp(av[1], "-?") == 0))
{
usage(ac == 2);

View File

@ -35,6 +35,10 @@
#include "../../jrd/trace/TraceService.h"
#include "../../jrd/ibase.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
namespace Firebird {
class TraceSvcUtil : public TraceSvcIntf
@ -320,6 +324,10 @@ int CLIB_ROUTINE main(int argc, char* argv[])
* Invoke real trace main function
*
**************************************/
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
prevCtrlCHandler = signal(SIGINT, ctrl_c_handler);

View File

@ -31,6 +31,10 @@
#include "../common/classes/auto.h"
#include "../common/SimpleStatusVector.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
int CLIB_ROUTINE main(int argc, char* argv[])
{
@ -44,6 +48,11 @@ int CLIB_ROUTINE main(int argc, char* argv[])
* Invoke real gsec main function
*
**************************************/
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
try
{
Firebird::AutoPtr<Firebird::UtilSvc> uSvc(Firebird::UtilSvc::createStandalone(argc, argv));

View File

@ -31,6 +31,10 @@
#include "../common/classes/auto.h"
#include "../common/SimpleStatusVector.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
int CLIB_ROUTINE main(int argc, char* argv[])
{
@ -44,6 +48,11 @@ int CLIB_ROUTINE main(int argc, char* argv[])
* Invoke real gstat main function
*
**************************************/
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
try
{
Firebird::AutoPtr<Firebird::UtilSvc> uSvc(Firebird::UtilSvc::createStandalone(argc, argv));

View File

@ -30,6 +30,10 @@
#include "../utilities/nbackup/nbk_proto.h"
#include "../common/classes/auto.h"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
int CLIB_ROUTINE main(int argc, char* argv[])
{
@ -43,6 +47,11 @@ int CLIB_ROUTINE main(int argc, char* argv[])
* Invoke real nbackup main function
*
**************************************/
#ifdef HAVE_LOCALE_H
// Pick up the system locale to allow SYSTEM<->UTF8 conversions
setlocale(LC_CTYPE, "");
#endif
try
{
Firebird::AutoPtr<Firebird::UtilSvc> uSvc(Firebird::UtilSvc::createStandalone(argc, argv));

View File

@ -25,12 +25,13 @@
#include "firebird.h"
#include <stdlib.h>
#include <string.h>
#include "../dsql/chars.h"
//#include "../dsql/chars.h"
#include "../yvalve/prepa_proto.h"
#include "../yvalve/gds_proto.h"
#include "../yvalve/YObjects.h"
#include "../common/classes/ClumpletWriter.h"
#include "../common/StatusArg.h"
#include "../common/Tokens.h"
#include <firebird/Interface.h>
@ -52,15 +53,11 @@ enum pp_vals {
const size_t MAX_TOKEN_SIZE = 1024;
static void generate_error(Firebird::CheckStatusWrapper*, const Firebird::string&, SSHORT, SSHORT);
static SSHORT get_next_token(const SCHAR**, const SCHAR*, Firebird::string&);
static SSHORT get_token(Firebird::CheckStatusWrapper*, SSHORT, bool, const SCHAR**, const SCHAR* const,
Firebird::string&);
static void generate_error(const Firebird::NoCaseString&, SSHORT, char = 0);
struct pp_table
{
SCHAR symbol[10];
USHORT length;
SSHORT code;
};
@ -68,22 +65,23 @@ struct pp_table
// Should delete SCHEMA in the future.
static const pp_table pp_symbols[] =
{
{"CREATE", 6, PP_CREATE},
{"DATABASE", 8, PP_DATABASE},
{"SCHEMA", 6, PP_SCHEMA},
{"PAGE_SIZE", 9, PP_PAGE_SIZE},
{"USER", 4, PP_USER},
{"PASSWORD", 8, PP_PASSWORD},
{"PAGESIZE", 8, PP_PAGESIZE},
{"LENGTH", 6, PP_LENGTH},
{"PAGES", 5, PP_PAGES},
{"PAGE", 4, PP_PAGE},
{"SET", 3, PP_SET},
{"NAMES", 5, PP_NAMES},
{"ROLE", 4, PP_ROLE},
{"", 0, 0}
{"CREATE", PP_CREATE},
{"DATABASE", PP_DATABASE},
{"SCHEMA", PP_SCHEMA},
{"PAGE_SIZE", PP_PAGE_SIZE},
{"USER", PP_USER},
{"PASSWORD", PP_PASSWORD},
{"PAGESIZE", PP_PAGESIZE},
{"LENGTH", PP_LENGTH},
{"PAGES", PP_PAGES},
{"PAGE", PP_PAGE},
{"SET", PP_SET},
{"NAMES", PP_NAMES},
{"ROLE", PP_ROLE},
{"", 0}
};
// define the tokens
enum token_vals {
@ -96,9 +94,55 @@ enum token_vals {
SYMBOL = 259
};
static const char* quotes = "\"\'";
using namespace Firebird;
static NoCaseString getToken(unsigned& pos, const Tokens& toks, int symbol = SYMBOL)
{
if (pos >= toks.getCount())
generate_error("", UNEXPECTED_END_OF_COMMAND);
NoCaseString curTok(NoCaseString(toks[pos].text, toks[pos].length));
switch(symbol)
{
case SYMBOL:
break;
case STRING:
if (!strchr(quotes, toks[pos].text[0]))
generate_error(curTok, UNEXPECTED_TOKEN);
return toks[pos++].stripped().ToNoCaseString();
case NUMERIC:
{
const char* const end = &toks[pos].text[toks[pos].length];
for (const char* ptr = toks[pos].text; ptr < end; ++ptr)
{
if (*ptr < '0' || *ptr > '9')
generate_error(curTok, UNEXPECTED_TOKEN);
}
}
break;
default:
if (symbol > 0 && symbol <= 127) // good ascii symbol
{
if (toks[pos].length != 1 || toks[pos].text[0] != symbol)
generate_error(curTok, UNEXPECTED_TOKEN);
}
fb_assert(false);
break;
}
++pos;
return curTok;
}
/**
PREPARSE_execute
@ -126,31 +170,21 @@ bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt,
Arg::Gds(isc_command_end_err).raise();
}
if (!stmt_length)
stmt_length = static_cast<USHORT>(strlen(stmt));
const char* const stmt_end = stmt + stmt_length;
string token;
Tokens tks(stmt_length, stmt, sqlSpaces, quotes, sqlComments);
unsigned pos = 0;
if (get_token(status, SYMBOL, false, &stmt, stmt_end, token) ||
token.length() != pp_symbols[PP_CREATE].length || token != pp_symbols[PP_CREATE].symbol)
if (getToken(pos, tks) != pp_symbols[PP_CREATE].symbol)
{
return false;
}
if (get_token(status, SYMBOL, false, &stmt, stmt_end, token) ||
(token.length() != pp_symbols[PP_DATABASE].length &&
token.length() != pp_symbols[PP_SCHEMA].length) ||
(token != pp_symbols[PP_DATABASE].symbol && token != pp_symbols[PP_SCHEMA].symbol))
NoCaseString token(getToken(pos, tks));
if (token != pp_symbols[PP_DATABASE].symbol && token != pp_symbols[PP_SCHEMA].symbol)
{
return false;
}
if (get_token(status, STRING, false, &stmt, stmt_end, token))
{
return true;
}
PathName file_name(token.ToPathName());
PathName file_name(getToken(pos, tks, STRING).ToPathName());
*stmt_eaten = false;
ClumpletWriter dpb(ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1);
@ -160,22 +194,21 @@ bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt,
SLONG page_size = 0;
bool matched;
do {
const SSHORT result = get_next_token(&stmt, stmt_end, token);
if (result == NO_MORE_TOKENS)
try
{
token = getToken(pos, tks);
}
catch (const Exception&)
{
*stmt_eaten = true;
break;
}
if (result < 0)
break;
matched = false;
for (int i = 3; pp_symbols[i].length && !matched; i++)
for (int i = 3; pp_symbols[i].symbol[0] && !matched; i++)
{
if (token.length() == pp_symbols[i].length && token == pp_symbols[i].symbol)
if (token == pp_symbols[i].symbol)
{
bool get_out = false;
// CVC: What's strange, this routine doesn't check token.length()
// but it proceeds blindly, trying to exhaust the token itself.
@ -183,74 +216,52 @@ bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt,
{
case PP_PAGE_SIZE:
case PP_PAGESIZE:
if (get_token(status, '=', true, &stmt, stmt_end, token) ||
get_token(status, NUMERIC, false, &stmt, stmt_end, token))
{
get_out = true;
break;
}
token = getToken(pos, tks);
if (token == "=")
token = getToken(pos, tks, NUMERIC);
page_size = atol(token.c_str());
dpb.insertInt(isc_dpb_page_size, page_size);
matched = true;
break;
case PP_USER:
if (get_token(status, STRING, false, &stmt, stmt_end, token))
{
get_out = true;
break;
}
token = getToken(pos, tks);
dpb.insertString(isc_dpb_user_name, token);
dpb.insertString(isc_dpb_user_name, token.ToString());
matched = true;
break;
case PP_PASSWORD:
if (get_token(status, STRING, false, &stmt, stmt_end, token))
{
get_out = true;
break;
}
token = getToken(pos, tks, STRING);
dpb.insertString(isc_dpb_password, token);
dpb.insertString(isc_dpb_password, token.ToString());
matched = true;
break;
case PP_ROLE:
if (get_token(status, STRING, false, &stmt, stmt_end, token))
{
get_out = true;
break;
}
token = getToken(pos, tks);
dpb.insertString(isc_dpb_sql_role_name, token);
dpb.insertString(isc_dpb_sql_role_name, token.ToString());
matched = true;
break;
case PP_SET:
if (get_token(status, SYMBOL, false, &stmt, stmt_end, token) ||
token.length() != pp_symbols[PP_NAMES].length ||
token != pp_symbols[PP_NAMES].symbol ||
get_token(status, STRING, false, &stmt, stmt_end, token))
{
get_out = true;
break;
}
token = getToken(pos, tks);
if (token != pp_symbols[PP_NAMES].symbol)
generate_error(token, UNEXPECTED_TOKEN);
token = getToken(pos, tks, STRING);
dpb.insertString(isc_dpb_lc_ctype, token);
dpb.insertString(isc_dpb_lc_ctype, token.ToString());
matched = true;
break;
case PP_LENGTH:
token = getToken(pos, tks);
if (token == "=")
token = getToken(pos, tks, NUMERIC);
// Skip a token for value
if (get_token(status, '=', true, &stmt, stmt_end, token) ||
get_token(status, NUMERIC, false, &stmt, stmt_end, token))
{
get_out = true;
break;
}
matched = true;
break;
@ -258,14 +269,9 @@ bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt,
case PP_PAGES:
matched = true;
break;
}
if (get_out) {
return true;
}
} // switch
} // if
} // for
} while (matched);
RefPtr<Why::Dispatcher> dispatcher(new Why::Dispatcher);
@ -294,7 +300,7 @@ bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt,
@param result
**/
static void generate_error(CheckStatusWrapper* status, const string& token, SSHORT error, SSHORT result)
static void generate_error(const NoCaseString& token, SSHORT error, char result)
{
string err_string;
@ -316,12 +322,12 @@ static void generate_error(CheckStatusWrapper* status, const string& token, SSHO
case TOKEN_TOO_LONG:
if (result)
{
err_string.assign(1, (TEXT) result);
err_string += token;
err_string += (TEXT) result;
err_string = result;
err_string += token.ToString();
err_string += result;
}
else
err_string = token;
err_string = token.ToString();
temp_status[5] = isc_token_err;
temp_status[6] = isc_arg_gds;
temp_status[7] = isc_random;
@ -331,201 +337,5 @@ static void generate_error(CheckStatusWrapper* status, const string& token, SSHO
break;
}
status->setErrors(temp_status);
}
/**
get_next_token
@brief
@param stmt
@param stmt_end
@param token
**/
static SSHORT get_next_token(const SCHAR** stmt, const SCHAR* stmt_end, string& token)
{
UCHAR c, char_class = 0;
token.erase();
const SCHAR* s = *stmt;
for (;;)
{
if (s >= stmt_end)
{
*stmt = s;
return NO_MORE_TOKENS;
}
c = *s++;
if (c == '/' && s < stmt_end && *s == '*')
{
s++;
while (s < stmt_end)
{
c = *s++;
if (c == '*' && s < stmt_end && *s == '/')
break;
}
s++;
continue;
}
// CVC: Dmitry told me to leave this in peace, but if somebody wants
// to experiment ignoring single line comments, here's an idea.
if (c == '-' && s < stmt_end && *s == '-')
{
s++;
while (s < stmt_end)
{
c = *s++;
if (c == '\n')
break;
}
continue;
}
// CVC: End modification.
char_class = classes(c);
if (!(char_class & CHR_WHITE))
break;
}
// At this point c contains character and class contains character class.
// s is pointing to next character.
const SCHAR* const start_of_token = s - 1;
// In here we handle only 4 cases, STRING, INTEGER, arbitrary
// SYMBOL and single character punctuation.
if (char_class & CHR_QUOTE)
{
for (;;)
{
if (s >= stmt_end)
return UNEXPECTED_END_OF_COMMAND;
// *s is quote - if next != quote we're at the end
if ((*s == c) && ((++s == stmt_end) || (*s != c)))
break;
token += *s++;
}
*stmt = s;
if (token.length() > MAX_TOKEN_SIZE)
{
// '=' used as then there is no place for null termination
token.erase(MAX_TOKEN_SIZE);
return TOKEN_TOO_LONG;
}
return STRING;
}
// Is it an integer?
if (char_class & CHR_DIGIT)
{
for (; s < stmt_end && (classes(c = *s) & CHR_DIGIT); ++s); // empty body
fb_assert(s >= start_of_token);
const FB_SIZE_T length = static_cast<FB_SIZE_T>(s - start_of_token);
*stmt = s;
if (length > MAX_TOKEN_SIZE)
{
token.assign(start_of_token, MAX_TOKEN_SIZE);
return TOKEN_TOO_LONG;
}
token.assign(start_of_token, length);
return NUMERIC;
}
// Is is a symbol?
if (char_class & CHR_LETTER)
{
token += UPPER(c);
for (; s < stmt_end && (classes(*s) & CHR_IDENT); s++) {
token += UPPER(*s);
}
*stmt = s;
if (token.length() > MAX_TOKEN_SIZE)
{
token.erase(MAX_TOKEN_SIZE);
return TOKEN_TOO_LONG;
}
return SYMBOL;
}
// What remains at this point for us is the single character punctuation.
*stmt = s;
return (c == ';' ? NO_MORE_TOKENS : c);
}
/**
get_token
@brief
@param status
@param token_type
@param optional
@param stmt
@param stmt_end
@param token
**/
static SSHORT get_token(CheckStatusWrapper* status,
SSHORT token_type,
bool optional,
const SCHAR** stmt,
const SCHAR* const stmt_end,
string& token)
{
const SCHAR* temp_stmt = *stmt;
const SSHORT result = get_next_token(&temp_stmt, stmt_end, token);
switch (result)
{
case NO_MORE_TOKENS:
*stmt = temp_stmt;
generate_error(status, token, UNEXPECTED_END_OF_COMMAND, 0);
return FB_FAILURE;
case UNEXPECTED_END_OF_COMMAND:
case TOKEN_TOO_LONG:
*stmt = temp_stmt;
// generate error here
generate_error(status, token, result, 0);
return FB_FAILURE;
}
// Some token was found
if (result == token_type)
{
*stmt = temp_stmt;
return FB_SUCCESS;
}
if (optional)
return FB_SUCCESS;
// generate error here and return failure;
*stmt = temp_stmt;
generate_error(status, token, UNEXPECTED_TOKEN,
(result == STRING) ? *(temp_stmt - 1) : 0);
return FB_FAILURE;
Arg::StatusVector(temp_status).raise();
}