[PATCH v4 04/33] lib: Fix a few bugs in trailing_strtoln()

Simon Glass sjg at chromium.org
Sun Mar 6 13:49:47 CET 2022


At present this has a minor bug in that it reads the byte before the
start of the string, if it is empty. Also it doesn't handle a
non-numeric prefix which is only one character long.

Fix these bugs with a reworked implementation. Add a test for the second
case. The first one is hard to test.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v4:
- Correct the commit tag
- Reword the commit message
- Update the function comment to clarify its intert / limitations

 include/vsprintf.h |  3 +++
 lib/strto.c        | 11 ++++++-----
 test/str_ut.c      |  2 ++
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/include/vsprintf.h b/include/vsprintf.h
index d4bf3211da..5172ceedec 100644
--- a/include/vsprintf.h
+++ b/include/vsprintf.h
@@ -98,6 +98,9 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base);
  * Given a string this finds a trailing number on the string and returns it.
  * For example, "abc123" would return 123.
  *
+ * Note that this does not handle a string without a prefix. See dectoul() for
+ * that case.
+ *
  * @str:	String to examine
  * Return: trailing number if found, else -1
  */
diff --git a/lib/strto.c b/lib/strto.c
index f191884376..b1d803a77d 100644
--- a/lib/strto.c
+++ b/lib/strto.c
@@ -189,11 +189,12 @@ long trailing_strtoln(const char *str, const char *end)
 
 	if (!end)
 		end = str + strlen(str);
-	if (isdigit(end[-1])) {
-		for (p = end - 1; p > str; p--) {
-			if (!isdigit(*p))
-				return dectoul(p + 1, NULL);
-		}
+	p = end - 1;
+	if (p > str && isdigit(*p)) {
+		do {
+			if (!isdigit(p[-1]))
+				return dectoul(p, NULL);
+		} while (--p > str);
 	}
 
 	return -1;
diff --git a/test/str_ut.c b/test/str_ut.c
index 9674a59f2a..058b359437 100644
--- a/test/str_ut.c
+++ b/test/str_ut.c
@@ -257,6 +257,8 @@ static int str_trailing(struct unit_test_state *uts)
 	ut_asserteq(123, trailing_strtoln(str1, str1 + 6));
 	ut_asserteq(-1, trailing_strtoln(str1, str1 + 9));
 
+	ut_asserteq(3, trailing_strtol("a3"));
+
 	return 0;
 }
 STR_TEST(str_trailing, 0);
-- 
2.35.1.616.g0bdcbb4464-goog



More information about the U-Boot mailing list