Skip to content

Commit

Permalink
Merge branch 'odbc-2.0' into odbc-3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
lawrinn committed May 19, 2017
2 parents ac3747b + 6a1619b commit 0f68677
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 17 deletions.
36 changes: 26 additions & 10 deletions ma_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void CloseMultiStatements(MADB_Stmt *Stmt)
}
MADB_FREE(Stmt->MultiStmts);
Stmt->MultiStmtCount= 0;
Stmt->stmt= NULL;
}


Expand Down Expand Up @@ -84,16 +85,24 @@ unsigned int GetMultiStatements(MADB_Stmt *Stmt, char *StmtStr, SQLINTEGER Lengt
{
end= StmtStr + Length - 1;
while (end > StmtStr && (isspace(*end) || *end == ';'))
{
--end;
Length= (SQLINTEGER)(end - StmtStr);
--Length;
}
}
p= StmtCopy= _strdup(StmtStr);
/* We can have here not NULL-terminated string as a source, thus we need to allocate, copy meaningful characters and
add NULL */
p= StmtCopy= MADB_ALLOC(Length + 1);
strncpy(StmtCopy, StmtStr, Length);
StmtCopy[Length]= '\0';

end= StmtCopy + Length;

while (p < StmtCopy + Length)
while (p < end)
{
if (wait_char)
{
if (*p == wait_char && *prev != '\\') /* What if that is escaped backslash? */
if (*p == wait_char && *prev != '\\')
{
wait_char= 0;
}
Expand All @@ -102,7 +111,7 @@ unsigned int GetMultiStatements(MADB_Stmt *Stmt, char *StmtStr, SQLINTEGER Lengt
{
switch (*p) {
case '-':
if (!STRING_OR_COMMENT() && (p < StmtCopy + Length + 1) && (char)*(p+1) == '-')
if (!STRING_OR_COMMENT() && (p < end - 1) && (char)*(p+1) == '-')
{
wait_char= '\n';
}
Expand All @@ -121,19 +130,26 @@ unsigned int GetMultiStatements(MADB_Stmt *Stmt, char *StmtStr, SQLINTEGER Lengt
}
break;
case '/':
if (!STRING_OR_COMMENT() && (p < StmtCopy + Length + 1) && (char)*(p+1) == '*')
if (!STRING_OR_COMMENT() && (p < end - 1) && (char)*(p+1) == '*')
comment= 1;
else if (comment && (p > StmtCopy) && (char)*(prev) == '*')
comment= 0;
break;
case '"':
if (prev && *prev != '\\')
quote[0] = !STRING_OR_COMMENT();
quote[0] = !STRING_OR_COMMENT();
break;
case '\'':
if (prev && *prev != '\\')
quote[1] = !STRING_OR_COMMENT();
quote[1] = !STRING_OR_COMMENT();
break;
case '\\':
/* *end is \0, so we are safe here to increment by 2 bytes */
if ((Stmt->Connection->mariadb->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) == 0 && p < end - 1)
{
/* Skipping escaped character and resetting prev */
p+= 2;
prev= 0;
continue;
}
default:
break;
}
Expand Down
49 changes: 43 additions & 6 deletions test/multistatement.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,14 @@ ODBC_TEST(test_semicolon)
return OK;
}

/* Double quote inside single quotes caused error in parsing while*/
ODBC_TEST(t_odbc_74)
/* Double quote inside single quotes caused error in parsing while
Also tests ODBC-97*/
ODBC_TEST(t_odbc74)
{
SQLCHAR ref[][4]={"\"", "'", "*/", "/*", "end", "one", "two"}, val[4];
SQLCHAR ref[][4]={"\"", "'", "*/", "/*", "end", "one\\", "two\\"}, val[8];
unsigned int i;
SQLHDBC hdbc1;
SQLHSTMT Stmt1;

OK_SIMPLE_STMT(Stmt, "DROP TABLE IF EXISTS odbc74; CREATE TABLE odbc74(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,\
val VARCHAR(64) NOT NULL)");
Expand All @@ -212,8 +215,8 @@ ODBC_TEST(t_odbc_74)
# ;Unhappy comment at the end ");
OK_SIMPLE_STMT(Stmt, "-- comment ;1 \n\
# comment ;2 \n\
INSERT INTO odbc74 (val) VALUES('one');\
INSERT INTO odbc74 (val) VALUES(\"two\");");
INSERT INTO odbc74 (val) VALUES('one\\\\');\
INSERT INTO odbc74 (val) VALUES(\"two\\\\\");");
OK_SIMPLE_STMT(Stmt, "SELECT val FROM odbc74 ORDER BY id");

for (i= 0; i < sizeof(ref)/sizeof(ref[0]); ++i)
Expand All @@ -224,11 +227,44 @@ ODBC_TEST(t_odbc_74)
EXPECT_STMT(Stmt, SQLFetch(Stmt), SQL_NO_DATA);
CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_CLOSE));

OK_SIMPLE_STMT(Stmt, "TRUNCATE TABLE odbc74");

AllocEnvConn(&Env, &hdbc1);
Stmt1= DoConnect(&hdbc1, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL);
FAIL_IF(Stmt1 == NULL, "Could not connect and/or allocate");

OK_SIMPLE_STMT(Stmt1, "SET @@SESSION.sql_mode='NO_BACKSLASH_ESCAPES'");

OK_SIMPLE_STMT(Stmt1, "INSERT INTO odbc74 (val) VALUES('one\\');\
INSERT INTO odbc74 (val) VALUES(\"two\\\");");
OK_SIMPLE_STMT(Stmt1, "SELECT val FROM odbc74 ORDER BY id");

/* We only have to last rows */
for (i= sizeof(ref)/sizeof(ref[0]) - 2; i < sizeof(ref)/sizeof(ref[0]); ++i)
{
CHECK_STMT_RC(Stmt1, SQLFetch(Stmt1));
IS_STR(my_fetch_str(Stmt1, val, 1), ref[i], sizeof(ref[i]));
}
EXPECT_STMT(Stmt1, SQLFetch(Stmt1), SQL_NO_DATA);

CHECK_STMT_RC(Stmt1, SQLFreeStmt(Stmt1, SQL_DROP));
CHECK_DBC_RC(hdbc1, SQLDisconnect(hdbc1));
CHECK_DBC_RC(hdbc1, SQLFreeConnect(hdbc1));

OK_SIMPLE_STMT(Stmt, "DROP TABLE IF EXISTS odbc74");

return OK;
}

ODBC_TEST(t_odbc95)
{
EXPECT_STMT(Stmt, SQLPrepare(Stmt, "SELECT 1;INSERT INTO non_existing VALUES(2)", SQL_NTS), SQL_ERROR);
CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_DROP));
Stmt= NULL;

return OK;
}

MA_ODBC_TESTS my_tests[]=
{
{test_multi_statements, "test_multi_statements"},
Expand All @@ -237,7 +273,8 @@ MA_ODBC_TESTS my_tests[]=
{test_params, "test_params"},
{t_odbc_16, "test_odbc_16"},
{test_semicolon, "test_semicolon_in_string"},
{t_odbc_74, "test_odbc_74"},
{t_odbc74, "t_odbc74and_odbc97"},
{t_odbc95, "t_odbc95" },
{NULL, NULL}
};

Expand Down
5 changes: 4 additions & 1 deletion test/tap.h
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,10 @@ int run_tests(MA_ODBC_TESTS *tests)

buff_pos= buff_before_test;
*buff_pos= 0;
SQLFreeStmt(Stmt, SQL_DROP);
if (Stmt != NULL)
{
SQLFreeStmt(Stmt, SQL_DROP);
}
SQLAllocHandle(SQL_HANDLE_STMT, Connection, &Stmt);
/* reset Statement */
fflush(stdout);
Expand Down

0 comments on commit 0f68677

Please sign in to comment.