diff options
author | Simo Sorce <idra@samba.org> | 2010-03-07 20:20:45 -0500 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2010-03-09 15:23:49 -0500 |
commit | c05d13d3c2c5d516c55cec133ba635f528034862 (patch) | |
tree | f5899d71ae4a5f5b3bab879d4b01ce4d4bad2277 | |
parent | 9f53820de731ca1a7f06341958b43fcfccf82600 (diff) | |
download | samba-c05d13d3c2c5d516c55cec133ba635f528034862.tar.gz samba-c05d13d3c2c5d516c55cec133ba635f528034862.tar.bz2 samba-c05d13d3c2c5d516c55cec133ba635f528034862.zip |
s4:ldb fix escape parsing
sscanf can return also on short reads, in this case an invalid escape
sequence like '\1k' would be accepted, returning 1 as value and swallowing the
'k'. Use an auxiliar function to validate and convert hex escapes.
-rw-r--r-- | source4/lib/ldb/common/ldb_parse.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/source4/lib/ldb/common/ldb_parse.c b/source4/lib/ldb/common/ldb_parse.c index a5aa28bb5a..6d43000dbc 100644 --- a/source4/lib/ldb/common/ldb_parse.c +++ b/source4/lib/ldb/common/ldb_parse.c @@ -43,6 +43,26 @@ #include "ldb_private.h" #include "system/locale.h" +static int ldb_parse_hex2char(const char *x) +{ + if (isxdigit(x[0]) && isxdigit(x[1])) { + const char h1 = x[0], h2 = x[1]; + int c; + + if (h1 >= 'a') c = h1 - (int)'a' + 10; + else if (h1 >= 'A') c = h1 - (int)'A' + 10; + else if (h1 >= '0') c = h1 - (int)'0'; + c = c << 4; + if (h2 >= 'a') c += h2 - (int)'a' + 10; + else if (h1 >= 'A') c += h2 - (int)'A' + 10; + else if (h1 >= '0') c += h2 - (int)'0'; + + return c; + } + + return -1; +} + /* a filter is defined by: <filter> ::= '(' <filtercomp> ')' @@ -71,8 +91,10 @@ struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str) for (i=j=0;i<slen;i++) { if (str[i] == '\\') { - unsigned c; - if (sscanf(&str[i+1], "%02X", &c) != 1) { + int c; + + c = ldb_parse_hex2char(&str[i+1]); + if (c == -1) { talloc_free(ret.data); memset(&ret, 0, sizeof(ret)); return ret; |