<p>Michael Bradeen <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18376">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Michael Bradeen: Looks good to me, approved; Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">func_odbc: Add SQL_ESC_BACKSLASHES dialplan function.<br><br>Some databases depending on their configuration using backslashes<br>for escaping. When combined with the use of ' this can result in<br>a broken func_odbc query.<br><br>This change adds a SQL_ESC_BACKSLASHES dialplan function which can<br>be used to escape the backslashes.<br><br>This is done as a dialplan function instead of being always done<br>as some databases do not require this, and always doing it would<br>result in incorrect data being put into the database.<br><br>ASTERISK-29838<br><br>Change-Id: I152bf34899b96ddb09cca3e767254d8d78f0c83d<br>---<br>M configs/samples/func_odbc.conf.sample<br>A doc/CHANGES-staging/func_odbc_esc_backslashes.txt<br>M funcs/func_odbc.c<br>3 files changed, 46 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configs/samples/func_odbc.conf.sample b/configs/samples/func_odbc.conf.sample</span><br><span>index 706b9ce..32fb68b 100644</span><br><span>--- a/configs/samples/func_odbc.conf.sample</span><br><span>+++ b/configs/samples/func_odbc.conf.sample</span><br><span>@@ -32,6 +32,10 @@</span><br><span> ; to use the dialplan function SQL_ESC() to escape the data prior to its</span><br><span> ; inclusion in the SQL statement.</span><br><span> ;</span><br><span style="color: hsl(120, 100%, 40%);">+; If you have data which may potentially contain backslashes, you may wish to</span><br><span style="color: hsl(120, 100%, 40%);">+; use the dialplan function SQL_ESC_BACKSLASHES() to escape the backslashes.</span><br><span style="color: hsl(120, 100%, 40%);">+; Note that not all databases may require escaping of the backslashes.</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span> ;</span><br><span> ; The following options are available in this configuration file:</span><br><span> ;</span><br><span>diff --git a/doc/CHANGES-staging/func_odbc_esc_backslashes.txt b/doc/CHANGES-staging/func_odbc_esc_backslashes.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..087bb42</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/func_odbc_esc_backslashes.txt</span><br><span>@@ -0,0 +1,7 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: func_odbc</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+A SQL_ESC_BACKSLASHES dialplan function has been added which</span><br><span style="color: hsl(120, 100%, 40%);">+escapes backslashes. Usage of this is dependent on whether the</span><br><span style="color: hsl(120, 100%, 40%);">+database in use can use backslashes to escape ticks or not. If</span><br><span style="color: hsl(120, 100%, 40%);">+it can, then usage of this prevents a broken SQL query depending</span><br><span style="color: hsl(120, 100%, 40%);">+on how the SQL query is constructed.</span><br><span>diff --git a/funcs/func_odbc.c b/funcs/func_odbc.c</span><br><span>index f9fa971..e5c6944 100644</span><br><span>--- a/funcs/func_odbc.c</span><br><span>+++ b/funcs/func_odbc.c</span><br><span>@@ -96,6 +96,19 @@</span><br><span> <para>Example: SELECT foo FROM bar WHERE baz='${SQL_ESC(${ARG1})}'</para></span><br><span> </description></span><br><span> </function></span><br><span style="color: hsl(120, 100%, 40%);">+ <function name="SQL_ESC_BACKSLASHES" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+ <synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ Escapes backslashes for use in SQL statements.</span><br><span style="color: hsl(120, 100%, 40%);">+ </synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+ <syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <parameter name="string" required="true" /></span><br><span style="color: hsl(120, 100%, 40%);">+ </syntax></span><br><span style="color: hsl(120, 100%, 40%);">+ <description></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Used in SQL templates to escape data which may contain backslashes</span><br><span style="color: hsl(120, 100%, 40%);">+ <literal>\</literal> which are otherwise used to escape data.</para></span><br><span style="color: hsl(120, 100%, 40%);">+ <para>Example: SELECT foo FROM bar WHERE baz='${SQL_ESC(${SQL_ESC_BACKSLASHES(${ARG1})})}'</para></span><br><span style="color: hsl(120, 100%, 40%);">+ </description></span><br><span style="color: hsl(120, 100%, 40%);">+ </function></span><br><span> ***/</span><br><span> </span><br><span> static char *config = "func_odbc.conf";</span><br><span>@@ -1079,13 +1092,13 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int acf_escape(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+static int acf_escape(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len, char character)</span><br><span> {</span><br><span> char *out = buf;</span><br><span> </span><br><span> for (; *data && out - buf < len; data++) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (*data == '\'') {</span><br><span style="color: hsl(0, 100%, 40%);">- *out = '\'';</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*data == character) {</span><br><span style="color: hsl(120, 100%, 40%);">+ *out = character;</span><br><span> out++;</span><br><span> }</span><br><span> *out++ = *data;</span><br><span>@@ -1095,9 +1108,25 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int acf_escape_ticks(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return acf_escape(chan, cmd, data, buf, len, '\'');</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct ast_custom_function escape_function = {</span><br><span> .name = "SQL_ESC",</span><br><span style="color: hsl(0, 100%, 40%);">- .read = acf_escape,</span><br><span style="color: hsl(120, 100%, 40%);">+ .read = acf_escape_ticks,</span><br><span style="color: hsl(120, 100%, 40%);">+ .write = NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int acf_escape_backslashes(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return acf_escape(chan, cmd, data, buf, len, '\\');</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_custom_function escape_backslashes_function = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "SQL_ESC_BACKSLASHES",</span><br><span style="color: hsl(120, 100%, 40%);">+ .read = acf_escape_backslashes,</span><br><span> .write = NULL,</span><br><span> };</span><br><span> </span><br><span>@@ -1831,6 +1860,7 @@</span><br><span> </span><br><span> ast_config_destroy(cfg);</span><br><span> res |= ast_custom_function_register(&escape_function);</span><br><span style="color: hsl(120, 100%, 40%);">+ res |= ast_custom_function_register(&escape_backslashes_function);</span><br><span> ast_cli_register_multiple(cli_func_odbc, ARRAY_LEN(cli_func_odbc));</span><br><span> </span><br><span> AST_RWLIST_UNLOCK(&queries);</span><br><span>@@ -1850,6 +1880,7 @@</span><br><span> }</span><br><span> </span><br><span> res |= ast_custom_function_unregister(&escape_function);</span><br><span style="color: hsl(120, 100%, 40%);">+ res |= ast_custom_function_unregister(&escape_backslashes_function);</span><br><span> res |= ast_custom_function_unregister(&fetch_function);</span><br><span> res |= ast_unregister_application(app_odbcfinish);</span><br><span> ast_cli_unregister_multiple(cli_func_odbc, ARRAY_LEN(cli_func_odbc));</span><br><span></span><br></pre><div style="white-space:pre-wrap"></div><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18376">change 18376</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18376"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: certified/16.8 </div>
<div style="display:none"> Gerrit-Change-Id: I152bf34899b96ddb09cca3e767254d8d78f0c83d </div>
<div style="display:none"> Gerrit-Change-Number: 18376 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: Michael Bradeen <mbradeen@sangoma.com> </div>
<div style="display:none"> Gerrit-CC: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>