diff options
author | Nick Mathewson <nickm@torproject.org> | 2009-08-31 00:18:55 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2009-08-31 00:18:55 -0400 |
commit | 00b37f071d2c96612892340f5f883b869033d6a1 (patch) | |
tree | 35d484780d5ca53aae43a5a90e9d032c6b1c08a5 | |
parent | 0bb59f1c38eef467a353faf1a30cf93b64209a27 (diff) | |
download | tor-00b37f071d2c96612892340f5f883b869033d6a1.tar.gz tor-00b37f071d2c96612892340f5f883b869033d6a1.zip |
Revise parsing of time and memory units to handle spaces.
When we added support for fractional units (like 1.5 MB) I broke
support for giving units with no space (like 2MB). This patch should
fix that. It also adds a propoer tor_parse_double().
Fix for bug 1076. Bugfix on 0.2.2.1-alpha.
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | src/common/util.c | 11 | ||||
-rw-r--r-- | src/common/util.h | 2 | ||||
-rw-r--r-- | src/or/config.c | 33 |
4 files changed, 28 insertions, 20 deletions
@@ -3,6 +3,8 @@ Changes in version 0.2.2.2-alpha - 2009-09-?? - Fix an extremely rare infinite recursion bug that could occur if we tried to log a message after shutting down the log subsystem. Found by Matt Edman. Bugfix on 0.2.0.16-alpha. + - Fix parsing for memory or time units given without a space between + the number and the unit. Bugfix on 0.2.2.1-alpha; fixes bug 1076. Changes in version 0.2.2.1-alpha - 2009-08-26 diff --git a/src/common/util.c b/src/common/util.c index 234180c4d4..19839e23a1 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -735,6 +735,17 @@ tor_parse_ulong(const char *s, int base, unsigned long min, CHECK_STRTOX_RESULT(); } +/** As tor_parse_long(), but return a double. */ +double +tor_parse_double(const char *s, double min, double max, int *ok, char **next) +{ + char *endptr; + double r; + + r = strtod(s, &endptr); + CHECK_STRTOX_RESULT(); +} + /** As tor_parse_log, but return a unit64_t. Only base 10 is guaranteed to * work for now. */ uint64_t diff --git a/src/common/util.h b/src/common/util.h index c7741a64ac..bb384a2a33 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -182,6 +182,8 @@ long tor_parse_long(const char *s, int base, long min, long max, int *ok, char **next); unsigned long tor_parse_ulong(const char *s, int base, unsigned long min, unsigned long max, int *ok, char **next); +double tor_parse_double(const char *s, double min, double max, int *ok, + char **next); uint64_t tor_parse_uint64(const char *s, int base, uint64_t min, uint64_t max, int *ok, char **next); const char *hex_str(const char *from, size_t fromlen) ATTR_NONNULL((1)); diff --git a/src/or/config.c b/src/or/config.c index b7317c75d3..b475a333fb 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -4860,35 +4860,28 @@ config_parse_units(const char *val, struct unit_table_t *u, int *ok) uint64_t v = 0; double d = 0; int use_float = 0; - - smartlist_t *sl; + char *cp; tor_assert(ok); - sl = smartlist_create(); - smartlist_split_string(sl, val, NULL, - SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3); - if (smartlist_len(sl) < 1 || smartlist_len(sl) > 2) { - *ok = 0; - goto done; - } - - v = tor_parse_uint64(smartlist_get(sl,0), 10, 0, UINT64_MAX, ok, NULL); - if (!*ok) { - int r = sscanf(smartlist_get(sl,0), "%lf", &d); - if (r == 0 || d < 0) + v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp); + if (!*ok || (cp && *cp == '.')) { + d = tor_parse_double(val, 0, UINT64_MAX, ok, &cp); + if (!*ok) goto done; use_float = 1; } - if (smartlist_len(sl) == 1) { + if (!cp) { *ok = 1; v = use_float ? DBL_TO_U64(d) : v; goto done; } + cp = (char*) eat_whitespace(cp); + for ( ;u->unit;++u) { - if (!strcasecmp(u->unit, smartlist_get(sl,1))) { + if (!strcasecmp(u->unit, cp)) { if (use_float) v = u->multiplier * d; else @@ -4897,11 +4890,9 @@ config_parse_units(const char *val, struct unit_table_t *u, int *ok) goto done; } } - log_warn(LD_CONFIG, "Unknown unit '%s'.", (char*)smartlist_get(sl,1)); + log_warn(LD_CONFIG, "Unknown unit '%s'.", cp); *ok = 0; done: - SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); - smartlist_free(sl); if (*ok) return v; @@ -4916,7 +4907,9 @@ config_parse_units(const char *val, struct unit_table_t *u, int *ok) static uint64_t config_parse_memunit(const char *s, int *ok) { - return config_parse_units(s, memory_units, ok); + uint64_t u = config_parse_units(s, memory_units, ok); + printf("%s -> %d\n", s, (int)u); + return u; } /** Parse a string in the format "number unit", where unit is a unit of time. |