]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
func_odbc: Add SQL_ESC_BACKSLASHES dialplan function.
authorJoshua C. Colp <jcolp@sangoma.com>
Thu, 10 Feb 2022 12:02:23 +0000 (08:02 -0400)
committerJoshua Colp <jcolp@sangoma.com>
Thu, 14 Apr 2022 21:57:19 +0000 (16:57 -0500)
Some databases depending on their configuration using backslashes
for escaping. When combined with the use of ' this can result in
a broken func_odbc query.

This change adds a SQL_ESC_BACKSLASHES dialplan function which can
be used to escape the backslashes.

This is done as a dialplan function instead of being always done
as some databases do not require this, and always doing it would
result in incorrect data being put into the database.

ASTERISK-29838

Change-Id: I152bf34899b96ddb09cca3e767254d8d78f0c83d

configs/samples/func_odbc.conf.sample
doc/CHANGES-staging/func_odbc_esc_backslashes.txt [new file with mode: 0644]
funcs/func_odbc.c

index b825974ea780c7c697fd1c8dd8a83d224f819d00..fce8a9261228595829339b41d53b565a97d704e6 100644 (file)
 ; to use the dialplan function SQL_ESC() to escape the data prior to its
 ; inclusion in the SQL statement.
 ;
+; If you have data which may potentially contain backslashes, you may wish to
+; use the dialplan function SQL_ESC_BACKSLASHES() to escape the backslashes.
+; Note that not all databases may require escaping of the backslashes.
+;
 ;
 ; The following options are available in this configuration file:
 ;
diff --git a/doc/CHANGES-staging/func_odbc_esc_backslashes.txt b/doc/CHANGES-staging/func_odbc_esc_backslashes.txt
new file mode 100644 (file)
index 0000000..087bb42
--- /dev/null
@@ -0,0 +1,7 @@
+Subject: func_odbc
+
+A SQL_ESC_BACKSLASHES dialplan function has been added which
+escapes backslashes. Usage of this is dependent on whether the
+database in use can use backslashes to escape ticks or not. If
+it can, then usage of this prevents a broken SQL query depending
+on how the SQL query is constructed.
index 48619b135404f6e0083b30ea9c7bebcaa6545b3e..7e4e6a3bb78706abf448d887d77c8f6cc379ec32 100644 (file)
                        <para>Example: SELECT foo FROM bar WHERE baz='${SQL_ESC(${ARG1})}'</para>
                </description>
        </function>
+       <function name="SQL_ESC_BACKSLASHES" language="en_US">
+               <synopsis>
+                       Escapes backslashes for use in SQL statements.
+               </synopsis>
+               <syntax>
+                       <parameter name="string" required="true" />
+               </syntax>
+               <description>
+                       <para>Used in SQL templates to escape data which may contain backslashes
+                       <literal>\</literal> which are otherwise used to escape data.</para>
+                       <para>Example: SELECT foo FROM bar WHERE baz='${SQL_ESC(${SQL_ESC_BACKSLASHES(${ARG1})})}'</para>
+               </description>
+       </function>
  ***/
 
 static char *config = "func_odbc.conf";
@@ -1102,13 +1115,13 @@ end_acf_read:
        return 0;
 }
 
-static int acf_escape(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+static int acf_escape(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len, char character)
 {
        char *out = buf;
 
        for (; *data && out - buf < len; data++) {
-               if (*data == '\'') {
-                       *out = '\'';
+               if (*data == character) {
+                       *out = character;
                        out++;
                }
                *out++ = *data;
@@ -1118,9 +1131,25 @@ static int acf_escape(struct ast_channel *chan, const char *cmd, char *data, cha
        return 0;
 }
 
+static int acf_escape_ticks(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+       return acf_escape(chan, cmd, data, buf, len, '\'');
+}
+
 static struct ast_custom_function escape_function = {
        .name = "SQL_ESC",
-       .read = acf_escape,
+       .read = acf_escape_ticks,
+       .write = NULL,
+};
+
+static int acf_escape_backslashes(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+       return acf_escape(chan, cmd, data, buf, len, '\\');
+}
+
+static struct ast_custom_function escape_backslashes_function = {
+       .name = "SQL_ESC_BACKSLASHES",
+       .read = acf_escape_backslashes,
        .write = NULL,
 };
 
@@ -1858,6 +1887,7 @@ static int load_module(void)
 
        ast_config_destroy(cfg);
        res |= ast_custom_function_register(&escape_function);
+       res |= ast_custom_function_register(&escape_backslashes_function);
        ast_cli_register_multiple(cli_func_odbc, ARRAY_LEN(cli_func_odbc));
 
        AST_RWLIST_UNLOCK(&queries);
@@ -1877,6 +1907,7 @@ static int unload_module(void)
        }
 
        res |= ast_custom_function_unregister(&escape_function);
+       res |= ast_custom_function_unregister(&escape_backslashes_function);
        res |= ast_custom_function_unregister(&fetch_function);
        res |= ast_unregister_application(app_odbcfinish);
        ast_cli_unregister_multiple(cli_func_odbc, ARRAY_LEN(cli_func_odbc));