diff options
author | Mark Michelson <mmichelson@digium.com> | 2014-05-06 17:12:19 +0000 |
---|---|---|
committer | Mark Michelson <mmichelson@digium.com> | 2014-05-06 17:12:19 +0000 |
commit | 3f5d4516bdc63d398e850fd419b1b75bb2c1f212 (patch) | |
tree | f61a051a1edbed7115af3876d74ee9b6f012d22c | |
parent | 795ed566d939bf61705c3d75a38e3b55dc6e19c2 (diff) |
Ensure that all parts of SQL UPDATEs and DELETEs are encoded.
Patches:
res_config_odbc.patch by John Hardin (License #6512)
........
Merged revisions 413304 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 413305 from http://svn.asterisk.org/svn/asterisk/branches/11
........
Merged revisions 413306 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@413307 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r-- | res/res_config_odbc.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/res/res_config_odbc.c b/res/res_config_odbc.c index 7f6093a10..922923c96 100644 --- a/res/res_config_odbc.c +++ b/res/res_config_odbc.c @@ -59,6 +59,26 @@ struct custom_prepare_struct { unsigned long long skip; }; +#define ENCODE_CHUNK(buffer, s) \ + do { \ + char *eptr = buffer; \ + const char *vptr = s; \ + for (; *vptr && eptr < buffer + sizeof(buffer); vptr++) { \ + if (strchr("^;", *vptr)) { \ + /* We use ^XX, instead of %XX because '%' is a special character in SQL */ \ + snprintf(eptr, buffer + sizeof(buffer) - eptr, "^%02hhX", *vptr); \ + eptr += 3; \ + } else { \ + *eptr++ = *vptr; \ + } \ + } \ + if (eptr < buffer + sizeof(buffer)) { \ + *eptr = '\0'; \ + } else { \ + buffer[sizeof(buffer) - 1] = '\0'; \ + } \ + } while(0) + static void decode_chunk(char *chunk) { for (; *chunk; chunk++) { @@ -107,30 +127,23 @@ static SQLHSTMT custom_prepare(struct odbc_obj *obj, void *data) } ast_debug(1, "Parameter %d ('%s') = '%s'\n", x, field->name, newval); if (strchr(newval, ';') || strchr(newval, '^')) { - char *eptr = encodebuf; - const char *vptr = newval; - for (; *vptr && eptr < encodebuf + sizeof(encodebuf); vptr++) { - if (strchr("^;", *vptr)) { - /* We use ^XX, instead of %XX because '%' is a special character in SQL */ - snprintf(eptr, encodebuf + sizeof(encodebuf) - eptr, "^%02hhX", *vptr); - eptr += 3; - } else { - *eptr++ = *vptr; - } - } - if (eptr < encodebuf + sizeof(encodebuf)) { - *eptr = '\0'; - } else { - encodebuf[sizeof(encodebuf) - 1] = '\0'; - } + ENCODE_CHUNK(encodebuf, newval); ast_string_field_set(cps, encoding[x], encodebuf); newval = cps->encoding[x]; } SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(newval), 0, (void *)newval, 0, NULL); } - if (!ast_strlen_zero(cps->extra)) - SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(cps->extra), 0, (void *)cps->extra, 0, NULL); + if (!ast_strlen_zero(cps->extra)) { + if (strchr(cps->extra, ';') || strchr(cps->extra, '^')) { + ENCODE_CHUNK(encodebuf, cps->extra); + SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(encodebuf), 0, (void *)encodebuf, 0, NULL); + } + else { + SQLBindParameter(stmt, x++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(cps->extra), 0, (void *)cps->extra, 0, NULL); + } + } + return stmt; } |