summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-10-12 19:32:41 +0000
committerNick Mathewson <nickm@torproject.org>2004-10-12 19:32:41 +0000
commit19da1f36c285530d3a52c764ba1c464d3de88487 (patch)
tree99f7a572698b0bf711c9adb995da136637b0ad4a
parent1c757b917dc0b92cfa62de60457365a9789801c1 (diff)
downloadtor-19da1f36c285530d3a52c764ba1c464d3de88487.tar.gz
tor-19da1f36c285530d3a52c764ba1c464d3de88487.zip
Make a bounds-checking replacement for strtol with slightly easier error-checking in the common case
svn:r2452
-rw-r--r--src/common/util.c67
-rw-r--r--src/common/util.h4
2 files changed, 68 insertions, 3 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 6ff45a1cea..f765a83f31 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2051,10 +2051,9 @@ parse_addr_port(const char *addrport, char **address, uint32_t *addr,
colon = strchr(addrport, ':');
if (colon) {
_address = tor_strndup(addrport, colon-addrport);
- _port = atoi(colon+1);
- if (_port<1 || _port>65535) {
+ _port = (int) tor_parse_long(colon+1,10,1,65535,NULL,NULL);
+ if (!_port) {
log_fn(LOG_WARN, "Port '%s' out of range", colon+1);
- _port = 0;
ok = 0;
}
} else {
@@ -2084,6 +2083,68 @@ parse_addr_port(const char *addrport, char **address, uint32_t *addr,
return ok ? 0 : -1;
}
+/** Extract a long from the start of s, in the given numeric base. If
+ * there is unconverted data and next is provided, set *next to the
+ * first unconverted character. An error has occurred if no characters
+ * are converted; or if there are unconverted characters and next is NULL; or
+ * if the parsed value is not between min and max. When no error occurs,
+ * return the parsed value and set *ok (if provided) to 1. When an error
+ * ocurs, return 0 and set *ok (if provided) to 0.
+ */
+long
+tor_parse_long(const char *s, int base, long min, long max,
+ int *ok, char **next)
+{
+ char *endptr;
+ long r;
+
+ r = strtol(s, &endptr, base);
+ /* Was at least one character converted? */
+ if (endptr == s)
+ goto err;
+ /* Were there unexpected unconverted characters? */
+ if (!next && *endptr)
+ goto err;
+ /* Is r within limits? */
+ if (r < min || r > max)
+ goto err;
+
+ if (ok) *ok = 1;
+ if (next) *next = endptr;
+ return r;
+ err:
+ if (ok) *ok = 0;
+ if (next) *next = endptr;
+ return 0;
+}
+
+unsigned long
+tor_parse_ulong(const char *s, int base, unsigned long min,
+ unsigned long max, int *ok, char **next)
+{
+ char *endptr;
+ unsigned long r;
+
+ r = strtol(s, &endptr, base);
+ /* Was at least one character converted? */
+ if (endptr == s)
+ goto err;
+ /* Were there unexpected unconverted characters? */
+ if (!next && *endptr)
+ goto err;
+ /* Is r within limits? */
+ if (r < min || r > max)
+ goto err;
+
+ if (ok) *ok = 1;
+ if (next) *next = endptr;
+ return r;
+ err:
+ if (ok) *ok = 0;
+ if (next) *next = endptr;
+ return 0;
+}
+
#ifndef MS_WINDOWS
struct tor_mutex_t {
};
diff --git a/src/common/util.h b/src/common/util.h
index d3a3d62413..2b54012fa9 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -94,6 +94,10 @@ typedef enum {
int tor_strpartition(char *dest, size_t dest_len,
const char *s, const char *insert, size_t n,
part_finish_rule_t rule);
+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);
/* Some platforms segfault when you try to access a multi-byte type