summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/common
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2010-03-07 20:20:45 -0500
committerSimo Sorce <idra@samba.org>2010-03-09 15:23:49 -0500
commitc05d13d3c2c5d516c55cec133ba635f528034862 (patch)
treef5899d71ae4a5f5b3bab879d4b01ce4d4bad2277 /source4/lib/ldb/common
parent9f53820de731ca1a7f06341958b43fcfccf82600 (diff)
downloadsamba-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.
Diffstat (limited to 'source4/lib/ldb/common')
-rw-r--r--source4/lib/ldb/common/ldb_parse.c26
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;