mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-27612 Connect : check buffer sizes, fix string format errors
This commit is contained in:
@@ -201,7 +201,7 @@ my_bool BJNX::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm)
|
|||||||
p[--n] = 0;
|
p[--n] = 0;
|
||||||
} else if (!IsNum(p)) {
|
} else if (!IsNum(p)) {
|
||||||
// Wrong array specification
|
// Wrong array specification
|
||||||
sprintf(g->Message, "Invalid array specification %s", p);
|
snprintf(g->Message, sizeof(g->Message), "Invalid array specification %s", p);
|
||||||
return true;
|
return true;
|
||||||
} // endif p
|
} // endif p
|
||||||
|
|
||||||
|
@@ -5707,10 +5707,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
|
|||||||
if (ttp == TAB_UNDEF && !topt->http) {
|
if (ttp == TAB_UNDEF && !topt->http) {
|
||||||
topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
|
topt->type= (src) ? "MYSQL" : (tab) ? "PROXY" : "DOS";
|
||||||
ttp= GetTypeID(topt->type);
|
ttp= GetTypeID(topt->type);
|
||||||
sprintf(g->Message, "No table_type. Was set to %s", topt->type);
|
snprintf(g->Message, sizeof(g->Message), "No table_type. Was set to %s", topt->type);
|
||||||
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message);
|
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 0, g->Message);
|
||||||
} else if (ttp == TAB_NIY) {
|
} else if (ttp == TAB_NIY) {
|
||||||
sprintf(g->Message, "Unsupported table type %s", topt->type);
|
snprintf(g->Message, sizeof(g->Message), "Unsupported table type %s", topt->type);
|
||||||
rc= HA_ERR_INTERNAL_ERROR;
|
rc= HA_ERR_INTERNAL_ERROR;
|
||||||
goto err;
|
goto err;
|
||||||
#if defined(REST_SUPPORT)
|
#if defined(REST_SUPPORT)
|
||||||
|
@@ -123,7 +123,7 @@ my_bool JSNX::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
|
|||||||
p[--n] = 0;
|
p[--n] = 0;
|
||||||
} else if (!IsNum(p)) {
|
} else if (!IsNum(p)) {
|
||||||
// Wrong array specification
|
// Wrong array specification
|
||||||
sprintf(g->Message, "Invalid array specification %s", p);
|
snprintf(g->Message, sizeof(g->Message), "Invalid array specification %s", p);
|
||||||
return true;
|
return true;
|
||||||
} // endif p
|
} // endif p
|
||||||
|
|
||||||
|
@@ -399,6 +399,7 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
int w;
|
int w;
|
||||||
MYSQLC myc;
|
MYSQLC myc;
|
||||||
PQRYRES qrp = NULL;
|
PQRYRES qrp = NULL;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
if (!port)
|
if (!port)
|
||||||
port = mysqld_port;
|
port = mysqld_port;
|
||||||
@@ -406,8 +407,11 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db,
|
|||||||
if (!strnicmp(srcdef, "select ", 7) || strstr(srcdef, "%s")) {
|
if (!strnicmp(srcdef, "select ", 7) || strstr(srcdef, "%s")) {
|
||||||
query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 10);
|
query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 10);
|
||||||
|
|
||||||
if (strstr(srcdef, "%s"))
|
if ((p= strstr(srcdef, "%s")))
|
||||||
sprintf(query, srcdef, "1=1"); // dummy where clause
|
{
|
||||||
|
/* Replace %s with 1=1 */
|
||||||
|
sprintf(query, "%.*s1=1%s", (int) (p - srcdef), srcdef, p + 2); // dummy where clause
|
||||||
|
}
|
||||||
else
|
else
|
||||||
strcpy(query, srcdef);
|
strcpy(query, srcdef);
|
||||||
|
|
||||||
|
54
storage/connect/mysql-test/connect/r/misc.result
Normal file
54
storage/connect/mysql-test/connect/r/misc.result
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
execute immediate concat('create table t engine=CONNECT table_type=JSON',REPEAT('1',5000),
|
||||||
|
' FILE_NAME=''users.json'' HTTP=''http://localhost:4142'' URI=''/users''');
|
||||||
|
ERROR HY000: Unsupported table type JSON1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
|
||||||
|
execute immediate concat('create table t engine=CONNECT table_type=OEM module=''libname''
|
||||||
|
Option_list=''Myopt=foo'' subtype=''MYTYPE',REPEAT('1', 10000), '''');
|
||||||
|
ERROR HY000: Subtype string too long
|
||||||
|
execute immediate concat('create table t engine=CONNECT table_type=DBF file_name=''',
|
||||||
|
REPLACE(@@secure_file_priv,'\\','/'),'cust.dbf', REPEAT('1', 10000), '''');
|
||||||
|
ERROR HY000: Cannot open
|
||||||
|
create table t engine=connect table_type=mysql
|
||||||
|
CONNECTION='mysql://root@localhost:MASTER_MYPORT/test/foobar'
|
||||||
|
SRCDEF='SELECT 1,''%n'' FROM DUAL WHERE %s';
|
||||||
|
select *from t;
|
||||||
|
ERROR HY000: Got error 174 'MakeSQL: Wrong place holders specification' from CONNECT
|
||||||
|
drop table t;
|
||||||
|
create table t engine=connect table_type=mysql
|
||||||
|
CONNECTION='mysql://root@localhost:MASTER_MYPORT/test/foobar'
|
||||||
|
SRCDEF='SELECT 1,%n FROM DUAL WHERE %s';
|
||||||
|
ERROR HY000: (1064) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '%n FROM DUAL WHERE 1=1 LIMIT 0' at line 1 [SELECT 1,%n FROM DUAL WHERE 1=1 LIMIT 0]
|
||||||
|
create table t engine=connect table_type=mysql
|
||||||
|
CONNECTION='mysql://root@localhost:MASTER_MYPORT/test/foobar'
|
||||||
|
SRCDEF='SELECT 1 FROM DUAL WHERE %s';
|
||||||
|
select *from t;
|
||||||
|
1
|
||||||
|
1
|
||||||
|
drop table t;
|
||||||
|
create table beers (
|
||||||
|
`Name` char(16) xpath='brandName',
|
||||||
|
`Origin` char(16) xpath='origin',
|
||||||
|
`Description` char(32) xpath='details')
|
||||||
|
engine=CONNECT table_type=XML file_name='MYSQLTEST_VARDIR/tmp/beer.xml'
|
||||||
|
tabname='table' option_list='rownode=tr,colnode=td%n';
|
||||||
|
select * from beers;
|
||||||
|
Name Origin Description
|
||||||
|
NULL NULL NULL
|
||||||
|
NULL NULL NULL
|
||||||
|
drop table beers;
|
||||||
|
create table beers (
|
||||||
|
`Name` char(16) xpath='brandName',
|
||||||
|
`Origin` char(16) xpath='origin',
|
||||||
|
`Description` char(32) xpath='details')
|
||||||
|
engine=CONNECT table_type=XML file_name='MYSQLTEST_VARDIR/tmp/beer.xml'
|
||||||
|
tabname='table' option_list='rownode=tr,colnode=td';
|
||||||
|
insert into beers values('11','22','33');
|
||||||
|
drop table beers;
|
||||||
|
execute immediate CONCAT('create table jsampall
|
||||||
|
(Author char(128) jpath=''$.AUTHOR["', REPEAT('a',10000),'"]'')
|
||||||
|
engine=CONNECT table_type=JSON
|
||||||
|
file_name=''',REPLACE(@@secure_file_priv,'\\','/'),'tmp/test.json''');
|
||||||
|
select author from jsampall;
|
||||||
|
author
|
||||||
|
Jean-Christophe Bernadacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
William J. Pardi
|
||||||
|
drop table jsampall;
|
141
storage/connect/mysql-test/connect/t/misc.test
Normal file
141
storage/connect/mysql-test/connect/t/misc.test
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
|
||||||
|
# Overlong table type
|
||||||
|
--error ER_UNKNOWN_ERROR
|
||||||
|
execute immediate concat('create table t engine=CONNECT table_type=JSON',REPEAT('1',5000),
|
||||||
|
' FILE_NAME=''users.json'' HTTP=''http://localhost:4142'' URI=''/users''');
|
||||||
|
|
||||||
|
# Overlong subtype
|
||||||
|
--error ER_UNKNOWN_ERROR
|
||||||
|
execute immediate concat('create table t engine=CONNECT table_type=OEM module=''libname''
|
||||||
|
Option_list=''Myopt=foo'' subtype=''MYTYPE',REPEAT('1', 10000), '''');
|
||||||
|
|
||||||
|
|
||||||
|
# Overlong filename
|
||||||
|
--error ER_UNKNOWN_ERROR
|
||||||
|
execute immediate concat('create table t engine=CONNECT table_type=DBF file_name=''',
|
||||||
|
REPLACE(@@secure_file_priv,'\\','/'),'cust.dbf', REPEAT('1', 10000), '''');
|
||||||
|
|
||||||
|
|
||||||
|
# Format string in SRCDEF
|
||||||
|
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||||
|
eval create table t engine=connect table_type=mysql
|
||||||
|
CONNECTION='mysql://root@localhost:$MASTER_MYPORT/test/foobar'
|
||||||
|
SRCDEF='SELECT 1,''%n'' FROM DUAL WHERE %s';
|
||||||
|
--error ER_GET_ERRMSG
|
||||||
|
select *from t;
|
||||||
|
drop table t;
|
||||||
|
|
||||||
|
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||||
|
--error ER_UNKNOWN_ERROR
|
||||||
|
eval create table t engine=connect table_type=mysql
|
||||||
|
CONNECTION='mysql://root@localhost:$MASTER_MYPORT/test/foobar'
|
||||||
|
SRCDEF='SELECT 1,%n FROM DUAL WHERE %s';
|
||||||
|
|
||||||
|
--replace_result $MASTER_MYPORT MASTER_MYPORT
|
||||||
|
eval create table t engine=connect table_type=mysql
|
||||||
|
CONNECTION='mysql://root@localhost:$MASTER_MYPORT/test/foobar'
|
||||||
|
SRCDEF='SELECT 1 FROM DUAL WHERE %s';
|
||||||
|
select *from t;
|
||||||
|
drop table t;
|
||||||
|
|
||||||
|
write_file $MYSQLTEST_VARDIR/tmp/beer.xml;
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<Beers>
|
||||||
|
<table>
|
||||||
|
<th><td>Name</td><td>Origin</td><td>Description</td></th>
|
||||||
|
<tr>
|
||||||
|
<td><brandName>Huntsman</brandName></td>
|
||||||
|
<td><origin>Bath, UK</origin></td>
|
||||||
|
<td><details>Wonderful hop, light alcohol</details></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><brandName>Tuborg</brandName></td>
|
||||||
|
<td><origin>Danmark</origin></td>
|
||||||
|
<td><details>In small bottles</details></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</Beers>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
# Format string in colnode
|
||||||
|
eval create table beers (
|
||||||
|
`Name` char(16) xpath='brandName',
|
||||||
|
`Origin` char(16) xpath='origin',
|
||||||
|
`Description` char(32) xpath='details')
|
||||||
|
engine=CONNECT table_type=XML file_name='$MYSQLTEST_VARDIR/tmp/beer.xml'
|
||||||
|
tabname='table' option_list='rownode=tr,colnode=td%n';
|
||||||
|
select * from beers;
|
||||||
|
drop table beers;
|
||||||
|
|
||||||
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
|
eval create table beers (
|
||||||
|
`Name` char(16) xpath='brandName',
|
||||||
|
`Origin` char(16) xpath='origin',
|
||||||
|
`Description` char(32) xpath='details')
|
||||||
|
engine=CONNECT table_type=XML file_name='$MYSQLTEST_VARDIR/tmp/beer.xml'
|
||||||
|
tabname='table' option_list='rownode=tr,colnode=td';
|
||||||
|
insert into beers values('11','22','33');
|
||||||
|
drop table beers;
|
||||||
|
|
||||||
|
remove_file $MYSQLTEST_VARDIR/tmp/beer.xml;
|
||||||
|
|
||||||
|
write_file $MYSQLTEST_VARDIR/tmp/test.json;
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"ISBN": "9782212090819",
|
||||||
|
"LANG": "fr",
|
||||||
|
"SUBJECT": "applications",
|
||||||
|
"AUTHOR": [
|
||||||
|
{
|
||||||
|
"FIRSTNAME": "Jean-Christophe",
|
||||||
|
"LASTNAME": "Bernadac"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FIRSTNAME": "François",
|
||||||
|
"LASTNAME": "Knab"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"TITLE": "Construire une application XML",
|
||||||
|
"PUBLISHER": {
|
||||||
|
"NAME": "Eyrolles",
|
||||||
|
"PLACE": "Paris"
|
||||||
|
},
|
||||||
|
"DATEPUB": 1999
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ISBN": "9782840825685",
|
||||||
|
"LANG": "fr",
|
||||||
|
"SUBJECT": "applications",
|
||||||
|
"AUTHOR": [
|
||||||
|
{
|
||||||
|
"FIRSTNAME": "William J.",
|
||||||
|
"LASTNAME": "Pardi"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"TITLE": "XML en Action",
|
||||||
|
"TRANSLATED": {
|
||||||
|
"PREFIX": "adapté de l'anglais par",
|
||||||
|
"TRANSLATOR": {
|
||||||
|
"FIRSTNAME": "James",
|
||||||
|
"LASTNAME": "Guerin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PUBLISHER": {
|
||||||
|
"NAME": "Microsoft Press",
|
||||||
|
"PLACE": "Paris"
|
||||||
|
},
|
||||||
|
"DATEPUB": 1999
|
||||||
|
}
|
||||||
|
]
|
||||||
|
EOF
|
||||||
|
|
||||||
|
execute immediate CONCAT('create table jsampall
|
||||||
|
(Author char(128) jpath=''$.AUTHOR["', REPEAT('a',10000),'"]'')
|
||||||
|
engine=CONNECT table_type=JSON
|
||||||
|
file_name=''',REPLACE(@@secure_file_priv,'\\','/'),'tmp/test.json''');
|
||||||
|
|
||||||
|
select author from jsampall;
|
||||||
|
drop table jsampall;
|
||||||
|
remove_file $MYSQLTEST_VARDIR/tmp/test.json;
|
||||||
|
|
@@ -259,6 +259,12 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
|
|||||||
if (trace(2))
|
if (trace(2))
|
||||||
htrc("prefix=%s fn=%s path=%s\n", prefix, FileName, defpath);
|
htrc("prefix=%s fn=%s path=%s\n", prefix, FileName, defpath);
|
||||||
|
|
||||||
|
if (strlen(FileName) >= _MAX_PATH)
|
||||||
|
{
|
||||||
|
*pBuff= 0; /* Hope this is treated as error of some kind*/
|
||||||
|
return FileName;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strncmp(FileName, "//", 2) || !strncmp(FileName, "\\\\", 2)) {
|
if (!strncmp(FileName, "//", 2) || !strncmp(FileName, "\\\\", 2)) {
|
||||||
strcpy(pBuff, FileName); // Remote file
|
strcpy(pBuff, FileName); // Remote file
|
||||||
return pBuff;
|
return pBuff;
|
||||||
|
@@ -93,7 +93,12 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char* tab, char* db, bool info)
|
|||||||
if (check_valid_path(module, strlen(module))) {
|
if (check_valid_path(module, strlen(module))) {
|
||||||
strcpy(g->Message, "Module cannot contain a path");
|
strcpy(g->Message, "Module cannot contain a path");
|
||||||
return NULL;
|
return NULL;
|
||||||
} else
|
}
|
||||||
|
else if (strlen(subtype)+1+3 >= sizeof(getname)) {
|
||||||
|
strcpy(g->Message, "Subtype string too long");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
PlugSetPath(soname, module, GetPluginDir());
|
PlugSetPath(soname, module, GetPluginDir());
|
||||||
|
|
||||||
// The exported name is always in uppercase
|
// The exported name is always in uppercase
|
||||||
|
@@ -1788,7 +1788,7 @@ bool BSONCOL::SetArrayOptions(PGLOBAL g, char* p, int i, PSZ nm)
|
|||||||
p[--n] = 0;
|
p[--n] = 0;
|
||||||
} else if (!IsNum(p)) {
|
} else if (!IsNum(p)) {
|
||||||
// Wrong array specification
|
// Wrong array specification
|
||||||
sprintf(g->Message, "Invalid array specification %s for %s", p, Name);
|
snprintf(g->Message, sizeof(g->Message), "Invalid array specification %s for %s", p, Name);
|
||||||
return true;
|
return true;
|
||||||
} // endif p
|
} // endif p
|
||||||
|
|
||||||
|
@@ -286,6 +286,37 @@ int TDBEXT::Decode(PCSZ txt, char *buf, size_t n)
|
|||||||
return 0;
|
return 0;
|
||||||
} // end of Decode
|
} // end of Decode
|
||||||
|
|
||||||
|
/*
|
||||||
|
Count number of %s placeholders in string.
|
||||||
|
Returns -1 if other sprintf placeholders are found, .g %d
|
||||||
|
*/
|
||||||
|
static int count_placeholders(const char *fmt)
|
||||||
|
{
|
||||||
|
int cnt= 0;
|
||||||
|
for (const char *p=fmt; *p; p++)
|
||||||
|
{
|
||||||
|
if (*p == '%')
|
||||||
|
{
|
||||||
|
switch (p[1])
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
/* %s found */
|
||||||
|
cnt++;
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
/* masking char for % found */
|
||||||
|
p++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* some other placeholder found */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* MakeSrcdef: make the SQL statement from SRDEF option. */
|
/* MakeSrcdef: make the SQL statement from SRDEF option. */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
@@ -310,16 +341,29 @@ bool TDBEXT::MakeSrcdef(PGLOBAL g)
|
|||||||
? To_CondFil->Having : PlugDup(g, "1=1");
|
? To_CondFil->Having : PlugDup(g, "1=1");
|
||||||
} // endif ph
|
} // endif ph
|
||||||
|
|
||||||
if (!stricmp(ph, "W")) {
|
int n_placeholders = count_placeholders(Srcdef);
|
||||||
|
if (n_placeholders < 0)
|
||||||
|
{
|
||||||
|
strcpy(g->Message, "MakeSQL: Wrong place holders specification");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stricmp(ph, "W") && n_placeholders <= 1) {
|
||||||
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1));
|
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1));
|
||||||
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1));
|
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1));
|
||||||
} else if (!stricmp(ph, "WH")) {
|
}
|
||||||
|
else if (!stricmp(ph, "WH") && n_placeholders <= 2)
|
||||||
|
{
|
||||||
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
|
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
|
||||||
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1, fil2));
|
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1, fil2));
|
||||||
} else if (!stricmp(ph, "H")) {
|
}
|
||||||
|
else if (!stricmp(ph, "H") && n_placeholders <= 1)
|
||||||
|
{
|
||||||
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil2));
|
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil2));
|
||||||
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2));
|
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2));
|
||||||
} else if (!stricmp(ph, "HW")) {
|
}
|
||||||
|
else if (!stricmp(ph, "HW") && n_placeholders <= 2)
|
||||||
|
{
|
||||||
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
|
Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2));
|
||||||
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2, fil1));
|
Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2, fil1));
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1384,7 +1384,7 @@ bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
|
|||||||
p[--n] = 0;
|
p[--n] = 0;
|
||||||
} else if (!IsNum(p)) {
|
} else if (!IsNum(p)) {
|
||||||
// Wrong array specification
|
// Wrong array specification
|
||||||
sprintf(g->Message, "Invalid array specification %s for %s", p, Name);
|
snprintf(g->Message, sizeof(g->Message), "Invalid array specification %s for %s", p, Name);
|
||||||
return true;
|
return true;
|
||||||
} // endif p
|
} // endif p
|
||||||
|
|
||||||
|
@@ -904,6 +904,11 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
|
|||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
if (Mode == MODE_READ || Mode == MODE_READX) {
|
if (Mode == MODE_READ || Mode == MODE_READX) {
|
||||||
MakeSelect(g, Mode == MODE_READX);
|
MakeSelect(g, Mode == MODE_READX);
|
||||||
|
if (Mode == MODE_READ && !Query)
|
||||||
|
{
|
||||||
|
Myc.Close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
m_Rc = (Mode == MODE_READ)
|
m_Rc = (Mode == MODE_READ)
|
||||||
? Myc.ExecSQL(g, Query->GetStr()) : RC_OK;
|
? Myc.ExecSQL(g, Query->GetStr()) : RC_OK;
|
||||||
|
|
||||||
|
@@ -1511,8 +1511,12 @@ bool XMLCOL::ParseXpath(PGLOBAL g, bool mode)
|
|||||||
if (!mode)
|
if (!mode)
|
||||||
// Take care of an eventual extra column node a la html
|
// Take care of an eventual extra column node a la html
|
||||||
if (Tdbp->Colname) {
|
if (Tdbp->Colname) {
|
||||||
sprintf(pbuf, Tdbp->Colname, Rank + ((Tdbp->Usedom) ? 0 : 1));
|
char *p = strstr(Tdbp->Colname, "%d");
|
||||||
strcat(pbuf, "/");
|
if (p)
|
||||||
|
snprintf(pbuf, len + 3, "%.*s%d%s/", (int) (p - Tdbp->Colname), Tdbp->Colname,
|
||||||
|
Rank + (Tdbp->Usedom ? 0 : 1), p + 2);
|
||||||
|
else
|
||||||
|
snprintf(pbuf, len + 3, "%s/", Tdbp->Colname);
|
||||||
} // endif Colname
|
} // endif Colname
|
||||||
|
|
||||||
if (Xname) {
|
if (Xname) {
|
||||||
|
Reference in New Issue
Block a user