[PATCH] diagnose invalid host and port command line arguments; don't modify ARGV
Jim Meyering
jim at meyering.net
Mon Aug 8 10:08:54 UTC 2011
There was inadequate verification of command line HOST:PORT (-d and -m)
and -p PORT arguments and some duplicate code. The patch below factors
out the duplication and adds checks to catch/diagnose invalid inputs.
Along the way, it also resolves BZ 728623.
>From 9dbd0d54065531654b42224931f4abb2a6685374 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering at redhat.com>
Date: Mon, 8 Aug 2011 11:57:38 +0200
Subject: [PATCH] diagnose invalid host and port command line arguments; don't
modify ARGV
* rest.c (get_port, extract_host_port): New functions.
(main): Use them to parse arguments to the -d, -m and -p options.
Before, a missing host name part and/or an invalid port number
would not have been diagnosed.
By no longer modifying "optarg", this address
http://bugzilla.redhat.com/728623
---
rest.c | 52 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 39 insertions(+), 13 deletions(-)
diff --git a/rest.c b/rest.c
index a54fabd..6125275 100644
--- a/rest.c
+++ b/rest.c
@@ -51,6 +51,8 @@
#include "mpipe.h"
#include "state_defs.h"
#include "version-etc.h"
+#include "xstrndup.h"
+#include "xstrtol.h"
const char version_etc_copyright[] =
/* Do *not* mark this string for translation. %s is a copyright
@@ -2373,13 +2375,42 @@ Report %s bugs to %s.\n\
exit (status);
}
+/* Return the integer representation of PORT_STR. Exit nonzero if
+ PORT_STR is not a valid valid unsigned integer <= SHRT_MAX */
+static unsigned short
+get_port (char const *port_str)
+{
+ unsigned long port_tmp;
+ if (xstrtoul (port_str, NULL, 10, &port_tmp, NULL) != LONGINT_OK
+ || USHRT_MAX < port_tmp)
+ error (EXIT_FAILURE, 0, _("invalid port number: %s"), port_str);
+ return port_tmp;
+}
+
+/* Given a string S of the form "HOST:PORT_STR" or "HOST", set *HOSTNAME to a
+ malloc'd string containing HOST, and if there's a colon, set *PORT to the
+ port number. Diagnose and exit nonzero if the hostname part is empty
+ or if the port string is not a valid unsigned integer <= SHRT_MAX. */
+static void
+extract_host_port (char const *s, const char **hostname, unsigned short *port)
+{
+ assert (s);
+ size_t s_len = strlen (s);
+ char const *colon = memchr (s, ':', s_len);
+ size_t hostname_len = colon ? colon - s : s_len;
+ if (hostname_len == 0)
+ error (EXIT_FAILURE, 0, _("invalid host name"));
+ *hostname = xstrndup (s, hostname_len);
+
+ if (colon)
+ *port = get_port (colon + 1);
+}
+
int
main (int argc, char **argv)
{
struct MHD_Daemon *the_daemon;
sem_t the_sem;
- char *stctx = NULL;
- char *port_tmp;
bool autostart = false;
char *cfg_file = NULL;
@@ -2402,11 +2433,8 @@ main (int argc, char **argv)
break;
case 'd':
assert (optarg);
- db_host = strtok_r(optarg,":",&stctx);
- port_tmp = strtok_r(NULL,":",&stctx);
- if (port_tmp) {
- db_port = (unsigned short)strtoul(port_tmp,NULL,10);
- }
+ free (db_host); db_host = NULL;
+ extract_host_port (optarg, &db_host, &db_port);
break;
case 'l':
assert (optarg);
@@ -2414,14 +2442,12 @@ main (int argc, char **argv)
break;
case 'm':
assert (optarg);
- master_host = strtok_r(optarg,":",&stctx);
- port_tmp = strtok_r(NULL,":",&stctx);
- if (port_tmp) {
- master_port = (unsigned short)strtoul(port_tmp,NULL,10);
- }
+ free (master_host); master_host = NULL;
+ extract_host_port (optarg, &master_host, &master_port);
break;
case 'p':
- my_port = (unsigned short)strtoul(optarg,NULL,10);
+ assert (optarg);
+ my_port = get_port (optarg);
break;
case 'v':
++verbose;
--
1.7.6.351.gb35ac
More information about the iwhd-devel
mailing list