]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
sqlite3_prepare functions prepare only the next query in the string
authorNick Porter <nick@portercomputing.co.uk>
Thu, 18 Jan 2024 17:03:06 +0000 (17:03 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Mon, 22 Jan 2024 14:57:41 +0000 (14:57 +0000)
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.

src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c

index 65b7d9aba2527dddc7e2c49d6b2bb14db6013f29..3b2a01b9cde1248864e0950ac2cf926fcef67063 100644 (file)
@@ -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;
@@ -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;
                }
        }
@@ -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) {
@@ -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);
@@ -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);