2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-02 15:25:22 +00:00

util: Add function hexits_value() for parsing multiple hex digits.

Suggested-by: Justin Pettit <jpettit@nicira.com>
This commit is contained in:
Ben Pfaff
2010-11-15 10:18:10 -08:00
parent 96fc46e8fd
commit bf9712678f
8 changed files with 84 additions and 44 deletions

View File

@@ -746,20 +746,16 @@ json_lex_number(struct json_parser *p)
static const char * static const char *
json_lex_4hex(const char *cp, const char *end, int *valuep) json_lex_4hex(const char *cp, const char *end, int *valuep)
{ {
int value, i; unsigned int value;
if (cp + 4 > end) { if (cp + 4 > end) {
return "quoted string ends within \\u escape"; return "quoted string ends within \\u escape";
} }
value = 0; value = hexits_value(cp, 4, NULL);
for (i = 0; i < 4; i++) { if (value == UINT_MAX) {
unsigned char c = *cp++;
if (!isxdigit(c)) {
return "malformed \\u escape"; return "malformed \\u escape";
} }
value = (value << 4) | hexit_value(c);
}
if (!value) { if (!value) {
return "null bytes not supported in quoted strings"; return "null bytes not supported in quoted strings";
} }

View File

@@ -747,17 +747,15 @@ static const char *
parse_hex_bytes(struct ofpbuf *b, const char *s, unsigned int n) parse_hex_bytes(struct ofpbuf *b, const char *s, unsigned int n)
{ {
while (n--) { while (n--) {
int low, high;
uint8_t byte; uint8_t byte;
bool ok;
s += strspn(s, " "); s += strspn(s, " ");
low = hexit_value(*s); byte = hexits_value(s, 2, &ok);
high = low < 0 ? low : hexit_value(s[1]); if (!ok) {
if (low < 0 || high < 0) {
ovs_fatal(0, "%.2s: hex digits expected", s); ovs_fatal(0, "%.2s: hex digits expected", s);
} }
byte = 16 * low + high;
ofpbuf_put(b, &byte, 1); ofpbuf_put(b, &byte, 1);
s += 2; s += 2;
} }

View File

@@ -289,8 +289,8 @@ str_to_action(char *str, struct ofpbuf *b)
b->size -= sizeof nan->note; b->size -= sizeof nan->note;
while (arg && *arg != '\0') { while (arg && *arg != '\0') {
int high, low;
uint8_t byte; uint8_t byte;
bool ok;
if (*arg == '.') { if (*arg == '.') {
arg++; arg++;
@@ -299,16 +299,13 @@ str_to_action(char *str, struct ofpbuf *b)
break; break;
} }
high = hexit_value(*arg++); byte = hexits_value(arg, 2, &ok);
if (high >= 0) { if (!ok) {
low = hexit_value(*arg++);
}
if (high < 0 || low < 0) {
ovs_fatal(0, "bad hex digit in `note' argument"); ovs_fatal(0, "bad hex digit in `note' argument");
} }
byte = high * 16 + low;
ofpbuf_put(b, &byte, 1); ofpbuf_put(b, &byte, 1);
arg += 2;
} }
len = b->size - start_ofs; len = b->size - start_ofs;

View File

@@ -1,7 +1,7 @@
/* /*
* This file is from the Apache Portable Runtime Library. * This file is from the Apache Portable Runtime Library.
* The full upstream copyright and license statement is included below. * 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 /* 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; int i;
for (i = 0; i < SHA1_DIGEST_SIZE; 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; return false;
} }
digest[i] = (hexit_value(hex[0]) << 4) | hexit_value(hex[1]);
hex += 2; hex += 2;
} }
return true; return true;

View File

@@ -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 /* Returns the current working directory as a malloc()'d string, or a null
* pointer if the current working directory cannot be determined. */ * pointer if the current working directory cannot be determined. */
char * char *

View File

@@ -132,6 +132,7 @@ bool str_to_ullong(const char *, int base, unsigned long long *);
bool str_to_double(const char *, double *); bool str_to_double(const char *, double *);
int hexit_value(int c); int hexit_value(int c);
unsigned int hexits_value(const char *s, size_t n, bool *ok);
char *get_cwd(void); char *get_cwd(void);
char *dir_name(const char *file_name); char *dir_name(const char *file_name);

View File

@@ -156,23 +156,43 @@ uuid_from_string(struct uuid *uuid, const char *s)
bool bool
uuid_from_string_prefix(struct uuid *uuid, const char *s) uuid_from_string_prefix(struct uuid *uuid, const char *s)
{ {
static const char template[] = "00000000-1111-1111-2222-222233333333"; /* 0 1 2 3 */
const char *t; /* 012345678901234567890123456789012345 */
/* ------------------------------------ */
/* 00000000-1111-1111-2222-222233333333 */
uuid_zero(uuid); bool ok;
for (t = template; ; t++, s++) {
if (*t >= '0' && *t <= '3') { uuid->parts[0] = hexits_value(s, 8, &ok);
uint32_t *part = &uuid->parts[*t - '0']; if (!ok || s[8] != '-') {
if (!isxdigit(*s)) { 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; goto error;
} }
*part = (*part << 4) + hexit_value(*s);
} else if (*t == 0) {
return true; return true;
} else if (*t != *s) {
goto error;
}
}
error: error:
uuid_zero(uuid); uuid_zero(uuid);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009 Nicira Networks. * Copyright (c) 2009, 2010 Nicira Networks.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -28,13 +28,12 @@ hex_to_uint8(const char *input, uint8_t *output, size_t n)
goto error; goto error;
} }
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
unsigned char hi = input[i * 2]; bool ok;
unsigned char lo = input[i * 2 + 1];
if (!isxdigit(hi) || !isxdigit(lo)) { output[i] = hexits_value(&input[i * 2], 2, &ok);
if (!ok) {
goto error; goto error;
} }
output[i] = (hexit_value(hi) << 4) + hexit_value(lo);
} }
return; return;