Skip to content

Commit

Permalink
sqlite3_prepare functions prepare only the next query in the string
Browse files Browse the repository at this point in the history
and return a pointer to the character after what was parsed - so this
provides a more robust method of parsing the SQL to execute than simply
looking for ';' followed by '\n' or '\0'.

E.g. if there are comments which end the line with a ';' that fails with
the old parsing.
In addition, if there were ';' in data inside a string, the previous
parsing would have thrown away the portion of the string before that.
  • Loading branch information
ndptech committed Jan 22, 2024
1 parent 2a54430 commit 98f2f91
Showing 1 changed file with 13 additions and 16 deletions.
29 changes: 13 additions & 16 deletions src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,9 @@ static void sql_print_error(sqlite3 *db, int status, char const *fmt, ...)
static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db, char const *filename)
{
ssize_t len;
int statement_cnt = 0;
int statement_len, statement_cnt = 0;
char *buffer;
char *p, *q;
char const *p;
int cl;
FILE *f;
struct stat finfo;
Expand Down Expand Up @@ -308,7 +308,7 @@ static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db, char const *filename)
if ((*p != 0x0a) && (*p != 0x0d) && (*p != '\t')) break;
cl = 1;
} else {
cl = fr_utf8_char((uint8_t *) p, -1);
cl = fr_utf8_char((uint8_t const *) p, -1);
if (!cl) break;
}
}
Expand All @@ -319,21 +319,13 @@ static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db, char const *filename)
return -1;
}

/*
* Statement delimiter is ;\n
*/
p = buffer;
while ((q = strchr(p, ';'))) {
if ((q[1] != '\n') && (q[1] != '\0')) {
p = q + 1;
statement_cnt++;
continue;
}

while (*p) {
statement_len = len - (p - buffer);
#ifdef HAVE_SQLITE3_PREPARE_V2
status = sqlite3_prepare_v2(db, p, q - p, &statement, &z_tail);
status = sqlite3_prepare_v2(db, p, statement_len, &statement, &z_tail);
#else
status = sqlite3_prepare(db, p, q - p, &statement, &z_tail);
status = sqlite3_prepare(db, p, statement_len, &statement, &z_tail);
#endif

if (sql_check_error(db, status) != RLM_SQL_OK) {
Expand All @@ -342,6 +334,11 @@ static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db, char const *filename)
return -1;
}

/*
* No SQL statement was found
*/
if (!statement) break;

status = sqlite3_step(statement);
if (sql_check_error(db, status) != RLM_SQL_OK) {
sql_print_error(db, status, "Failed executing statement %i", statement_cnt);
Expand All @@ -358,7 +355,7 @@ static int sql_loadfile(TALLOC_CTX *ctx, sqlite3 *db, char const *filename)
}

statement_cnt++;
p = q + 1;
p = z_tail;
}

talloc_free(buffer);
Expand Down

0 comments on commit 98f2f91

Please sign in to comment.