2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +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 *
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)) {
value = hexits_value(cp, 4, NULL);
if (value == UINT_MAX) {
return "malformed \\u escape";
}
value = (value << 4) | hexit_value(c);
}
if (!value) {
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)
{
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;
}

View File

@@ -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;

View File

@@ -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;

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
* pointer if the current working directory cannot be determined. */
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 *);
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);

View File

@@ -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)) {
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;
}
*part = (*part << 4) + hexit_value(*s);
} else if (*t == 0) {
return true;
} else if (*t != *s) {
goto error;
}
}
error:
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");
* 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;
}
for (i = 0; i < n; i++) {
unsigned char hi = input[i * 2];
unsigned char lo = input[i * 2 + 1];
bool ok;
if (!isxdigit(hi) || !isxdigit(lo)) {
output[i] = hexits_value(&input[i * 2], 2, &ok);
if (!ok) {
goto error;
}
output[i] = (hexit_value(hi) << 4) + hexit_value(lo);
}
return;