s4:ldb fix escape parsing
authorSimo Sorce <idra@samba.org>
Mon, 8 Mar 2010 01:20:45 +0000 (20:20 -0500)
committerSimo Sorce <idra@samba.org>
Tue, 9 Mar 2010 20:23:49 +0000 (15:23 -0500)
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.

source4/lib/ldb/common/ldb_parse.c

index a5aa28bb5ab698a8fc2538e19ca9df353ea9e3f5..6d43000dbc70260e9815a631e981d0a8d41cffea 100644 (file)
 #include "ldb_private.h"
 #include "system/locale.h"
 
 #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> ')'
 /*
 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] == '\\') {
 
        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;
                                talloc_free(ret.data);
                                memset(&ret, 0, sizeof(ret));
                                return ret;