All of lore.kernel.org
 help / color / mirror / Atom feed
From: Harvey Harrison <harvey.harrison@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Alexey Dobriyan <adobriyan@gmail.com>
Subject: [PATCH 2/3] lib: vsnprintf.c remove macros defining strict string functions
Date: Tue, 13 May 2008 16:57:44 -0700	[thread overview]
Message-ID: <1210723064.6191.11.camel@brick> (raw)

Directly code the strict string conversion functions rather than using
defining macros.  Pull out a small helper to check the strict conditions
required at the end of a string (nul-terminated or newline).

Add additional checks in strict_strtol and strict_strtoll for numeric
overflow of the signed types.

Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
---
 lib/vsprintf.c |  145 +++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 97 insertions(+), 48 deletions(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index dc5c3ae..3547fb5 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -131,6 +131,19 @@ long long simple_strtoll(const char *cp,char **endp,unsigned int base)
 	return simple_strtoull(cp, endp, base);
 }
 
+/*
+ * Strictly check that the string is nul terminated or has a newline
+ * immediately following len chars.
+ */
+static int strict_checktail(size_t len, const char *cp, const char *tail)
+{
+	if ((*tail == '\0') ||
+	    ((len == (size_t)(tail - cp) + 1) && (*tail == '\n')))
+		return 1;
+	else
+		return 0;
+}
+
 /**
  * strict_strtoul - convert a string to an unsigned long strictly
  * @cp: The string to be converted
@@ -153,7 +166,26 @@ long long simple_strtoll(const char *cp,char **endp,unsigned int base)
  * simple_strtoul just ignores the successive invalid characters and
  * return the converted value of prefix part of the string.
  */
-int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
+int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
+{
+	char *tail;
+	unsigned long val;
+	size_t len;
+
+	*res = 0;
+	len = strlen(cp);
+	if (len == 0)
+		return -EINVAL;
+
+	val = simple_strtoul(cp, &tail, base);
+	if (strict_checktail(len, cp, tail)) {
+		*res = val;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(strict_strtoul);
 
 /**
  * strict_strtol - convert a string to a long strictly
@@ -167,7 +199,29 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
  * It returns 0 if conversion is successful and *res is set to the converted
  * value, otherwise it returns -EINVAL and *res is set to 0.
  */
-int strict_strtol(const char *cp, unsigned int base, long *res);
+int strict_strtol(const char *cp, unsigned int base, long *res)
+{
+	int ret;
+	unsigned long tmp;
+
+	if (*cp == '-')
+		ret = strict_strtoul(cp + 1, base, &tmp);
+	else
+		ret = strict_strtoul(cp, base, &tmp);
+
+	if (ret < 0 || tmp > LONG_MAX) {
+		*res = 0;
+		return -EINVAL;
+	}
+
+	if (*cp == '-')
+		*res = -tmp;
+	else
+		*res = tmp;
+
+	return 0;
+}
+EXPORT_SYMBOL(strict_strtol);
 
 /**
  * strict_strtoull - convert a string to an unsigned long long strictly
@@ -191,7 +245,26 @@ int strict_strtol(const char *cp, unsigned int base, long *res);
  * simple_strtoull just ignores the successive invalid characters and
  * return the converted value of prefix part of the string.
  */
-int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
+int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
+{
+	char *tail;
+	unsigned long long val;
+	size_t len;
+
+	*res = 0;
+	len = strlen(cp);
+	if (len == 0)
+		return -EINVAL;
+
+	val = simple_strtoull(cp, &tail, base);
+	if (strict_checktail(len, cp, tail)) {
+		*res = val;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(strict_strtoull);
 
 /**
  * strict_strtoll - convert a string to a long long strictly
@@ -205,53 +278,29 @@ int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
  * It returns 0 if conversion is successful and *res is set to the converted
  * value, otherwise it returns -EINVAL and *res is set to 0.
  */
-int strict_strtoll(const char *cp, unsigned int base, long long *res);
-
-#define define_strict_strtoux(type, valtype)				\
-int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\
-{									\
-	char *tail;							\
-	valtype val;							\
-	size_t len;							\
-									\
-	*res = 0;							\
-	len = strlen(cp);						\
-	if (len == 0)							\
-		return -EINVAL;						\
-									\
-	val = simple_strtoul(cp, &tail, base);				\
-	if ((*tail == '\0') ||						\
-		((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\
-		*res = val;						\
-		return 0;						\
-	}								\
-									\
-	return -EINVAL;							\
-}									\
-
-#define define_strict_strtox(type, valtype)				\
-int strict_strto##type(const char *cp, unsigned int base, valtype *res)	\
-{									\
-	int ret;							\
-	if (*cp == '-') {						\
-		ret = strict_strtou##type(cp+1, base, res);		\
-		if (!ret)						\
-			*res = -(*res);					\
-	} else								\
-		ret = strict_strtou##type(cp, base, res);		\
-									\
-	return ret;							\
-}									\
-
-define_strict_strtoux(l, unsigned long)
-define_strict_strtox(l, long)
-define_strict_strtoux(ll, unsigned long long)
-define_strict_strtox(ll, long long)
+int strict_strtoll(const char *cp, unsigned int base, long long *res)
+{
+	int ret;
+	unsigned long long tmp;
 
-EXPORT_SYMBOL(strict_strtoul);
-EXPORT_SYMBOL(strict_strtol);
+	if (*cp == '-')
+		ret = strict_strtoull(cp + 1, base, &tmp);
+	else
+		ret = strict_strtoull(cp, base, &tmp);
+
+	if (ret < 0 || tmp > LLONG_MAX) {
+		*res = 0;
+		return -EINVAL;
+	}
+
+	if (*cp == '-')
+		*res = -tmp;
+	else
+		*res = tmp;
+
+	return 0;
+}
 EXPORT_SYMBOL(strict_strtoll);
-EXPORT_SYMBOL(strict_strtoull);
 
 static int skip_atoi(const char **s)
 {
-- 
1.5.5.1.482.g0f174



                 reply	other threads:[~2008-05-13 23:58 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1210723064.6191.11.camel@brick \
    --to=harvey.harrison@gmail.com \
    --cc=adobriyan@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.