aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2010-11-15 10:18:10 -0800
committerBen Pfaff <blp@nicira.com>2010-11-15 10:18:10 -0800
commitbf9712678fc9ec85bf2ac54407e16d76aa22e7b6 (patch)
tree2052e512f4606aad7ec50bea03ccf33118e0b44a /lib
parent96fc46e8fdafd6467906e11e0fb493e2b78f2fb5 (diff)
util: Add function hexits_value() for parsing multiple hex digits.
Suggested-by: Justin Pettit <jpettit@nicira.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/json.c12
-rw-r--r--lib/nx-match.c8
-rw-r--r--lib/ofp-parse.c13
-rw-r--r--lib/sha1.c8
-rw-r--r--lib/util.c27
-rw-r--r--lib/util.h1
-rw-r--r--lib/uuid.c50
7 files changed, 80 insertions, 39 deletions
diff --git a/lib/json.c b/lib/json.c
index 5887f677..0a8bca27 100644
--- a/lib/json.c
+++ b/lib/json.c
@@ -746,19 +746,15 @@ json_lex_number(struct json_parser *p)
static const char *
json_lex_4hex(const char *cp, const char *end, int *valuep)
{
- int value, i;
+ unsigned int value;
if (cp + 4 > end) {
return "quoted string ends within \\u escape";
}
- value = 0;
- for (i = 0; i < 4; i++) {
- unsigned char c = *cp++;
- if (!isxdigit(c)) {
- return "malformed \\u escape";
- }
- value = (value << 4) | hexit_value(c);
+ value = hexits_value(cp, 4, NULL);
+ if (value == UINT_MAX) {
+ return "malformed \\u escape";
}
if (!value) {
return "null bytes not supported in quoted strings";
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 12ea4fb8..9f869a76 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -747,17 +747,15 @@ static const char *
parse_hex_bytes(struct ofpbuf *b, const char *s, unsigned int n)
{
while (n--) {
- int low, high;
uint8_t byte;
+ bool ok;
s += strspn(s, " ");
- low = hexit_value(*s);
- high = low < 0 ? low : hexit_value(s[1]);
- if (low < 0 || high < 0) {
+ byte = hexits_value(s, 2, &ok);
+ if (!ok) {
ovs_fatal(0, "%.2s: hex digits expected", s);
}
- byte = 16 * low + high;
ofpbuf_put(b, &byte, 1);
s += 2;
}
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 6b53f265..20440323 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -289,8 +289,8 @@ str_to_action(char *str, struct ofpbuf *b)
b->size -= sizeof nan->note;
while (arg && *arg != '\0') {
- int high, low;
uint8_t byte;
+ bool ok;
if (*arg == '.') {
arg++;
@@ -299,16 +299,13 @@ str_to_action(char *str, struct ofpbuf *b)
break;
}
- high = hexit_value(*arg++);
- if (high >= 0) {
- low = hexit_value(*arg++);
- }
- if (high < 0 || low < 0) {
+ byte = hexits_value(arg, 2, &ok);
+ if (!ok) {
ovs_fatal(0, "bad hex digit in `note' argument");
}
-
- byte = high * 16 + low;
ofpbuf_put(b, &byte, 1);
+
+ arg += 2;
}
len = b->size - start_ofs;
diff --git a/lib/sha1.c b/lib/sha1.c
index 205b82fe..3b16622d 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -1,7 +1,7 @@
/*
* This file is from the Apache Portable Runtime Library.
* The full upstream copyright and license statement is included below.
- * Modifications copyright (c) 2009 Nicira Networks.
+ * Modifications copyright (c) 2009, 2010 Nicira Networks.
*/
/* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -301,10 +301,12 @@ sha1_from_hex(uint8_t digest[SHA1_DIGEST_SIZE], const char *hex)
int i;
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
- if (!isxdigit(hex[0]) || !isxdigit(hex[1])) {
+ bool ok;
+
+ digest[i] = hexits_value(hex, 2, &ok);
+ if (!ok) {
return false;
}
- digest[i] = (hexit_value(hex[0]) << 4) | hexit_value(hex[1]);
hex += 2;
}
return true;
diff --git a/lib/util.c b/lib/util.c
index 12403cbb..4f1b9f75 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -364,6 +364,33 @@ hexit_value(int c)
}
}
+/* Returns the integer value of the 'n' hexadecimal digits starting at 's', or
+ * UINT_MAX if one of those "digits" is not really a hex digit. If 'ok' is
+ * nonnull, '*ok' is set to true if the conversion succeeds or to false if a
+ * non-hex digit is detected. */
+unsigned int
+hexits_value(const char *s, size_t n, bool *ok)
+{
+ unsigned int value;
+ size_t i;
+
+ value = 0;
+ for (i = 0; i < n; i++) {
+ int hexit = hexit_value(s[i]);
+ if (hexit < 0) {
+ if (ok) {
+ *ok = false;
+ }
+ return UINT_MAX;
+ }
+ value = (value << 4) + hexit;
+ }
+ if (ok) {
+ *ok = true;
+ }
+ return value;
+}
+
/* Returns the current working directory as a malloc()'d string, or a null
* pointer if the current working directory cannot be determined. */
char *
diff --git a/lib/util.h b/lib/util.h
index 6bc17404..703b93cf 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -132,6 +132,7 @@ bool str_to_ullong(const char *, int base, unsigned long long *);
bool str_to_double(const char *, double *);
int hexit_value(int c);
+unsigned int hexits_value(const char *s, size_t n, bool *ok);
char *get_cwd(void);
char *dir_name(const char *file_name);
diff --git a/lib/uuid.c b/lib/uuid.c
index 2aac4c72..e2590242 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -156,23 +156,43 @@ uuid_from_string(struct uuid *uuid, const char *s)
bool
uuid_from_string_prefix(struct uuid *uuid, const char *s)
{
- static const char template[] = "00000000-1111-1111-2222-222233333333";
- const char *t;
+ /* 0 1 2 3 */
+ /* 012345678901234567890123456789012345 */
+ /* ------------------------------------ */
+ /* 00000000-1111-1111-2222-222233333333 */
- uuid_zero(uuid);
- for (t = template; ; t++, s++) {
- if (*t >= '0' && *t <= '3') {
- uint32_t *part = &uuid->parts[*t - '0'];
- if (!isxdigit(*s)) {
- goto error;
- }
- *part = (*part << 4) + hexit_value(*s);
- } else if (*t == 0) {
- return true;
- } else if (*t != *s) {
- goto error;
- }
+ bool ok;
+
+ uuid->parts[0] = hexits_value(s, 8, &ok);
+ if (!ok || s[8] != '-') {
+ goto error;
+ }
+
+ uuid->parts[1] = hexits_value(s + 9, 4, &ok) << 16;
+ if (!ok || s[13] != '-') {
+ goto error;
+ }
+
+ uuid->parts[1] += hexits_value(s + 14, 4, &ok);
+ if (!ok || s[18] != '-') {
+ goto error;
+ }
+
+ uuid->parts[2] = hexits_value(s + 19, 4, &ok) << 16;
+ if (!ok || s[23] != '-') {
+ goto error;
+ }
+
+ uuid->parts[2] += hexits_value(s + 24, 4, &ok);
+ if (!ok) {
+ goto error;
+ }
+
+ uuid->parts[3] = hexits_value(s + 28, 8, &ok);
+ if (!ok) {
+ goto error;
}
+ return true;
error:
uuid_zero(uuid);