From 4b4858936fadd61a1696cb5408ab81330ddb5c14 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 8 Apr 2020 10:09:16 +0200 Subject: lib: strto: Stop detection when invalid char is used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This issue has been found when mtd partition are specified. Autodetection code should stop when the first invalid char is found. Here is the example of commands: setenv mtdids nand0=memory-controller@e000e000 setenv mtdparts "mtdparts=nand0:4m(boot),4m(env),64m(kernel),96m(rootfs)" mtd list Before: Zynq> mtd list List of MTD devices: * nand0 - type: NAND flash - block size: 0x20000 bytes - min I/O: 0x800 bytes - OOB size: 64 bytes - OOB available: 16 bytes - ECC strength: 1 bits - ECC step size: 2048 bytes - bitflip threshold: 1 bits - 0x000000000000-0x000010000000 : "nand0" - 0x000000000000-0x000000400000 : "boot" - 0x000000400000-0x000000800000 : "env" - 0x000000800000-0x000006c00000 : "kernel" - 0x000006c00000-0x000010000000 : "rootfs" Where it is visible that kernel partition has 100m instead of 64m After: Zynq> mtd list * nand0 - type: NAND flash - block size: 0x20000 bytes - min I/O: 0x800 bytes - OOB size: 64 bytes - OOB available: 16 bytes - ECC strength: 1 bits - ECC step size: 2048 bytes - bitflip threshold: 1 bits - 0x000000000000-0x000010000000 : "nand0" - 0x000000000000-0x000000400000 : "boot" - 0x000000400000-0x000000800000 : "env" - 0x000000800000-0x000004800000 : "kernel" - 0x000004800000-0x00000a800000 : "rootfs" Signed-off-by: Michal Simek Fixes: 0486497e2b5f ("lib: Improve _parse_integer_fixup_radix base 16 detection") Tested-by: Heiko Schocher Tested-by: Pali Rohár --- lib/strto.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib') diff --git a/lib/strto.c b/lib/strto.c index 1ac2b09c725..606701566f3 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -34,6 +34,9 @@ static const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) *base = 16; break; } + + if (!(var >= '0' && var <= '9')) + break; } while (var); } } -- cgit v1.3.1 From fdc79a6b125d52b6ca0fd65df538db7810d88a8d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 8 Apr 2020 08:32:56 -0600 Subject: lib: Add a function to convert a string to upper case Add a helper function for this operation. Update the strtoul() tests to check upper case as well. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt --- include/vsprintf.h | 12 +++++++++ lib/strto.c | 8 ++++++ test/str_ut.c | 78 +++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 83 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/include/vsprintf.h b/include/vsprintf.h index 56844dd2de8..d9fb68add0c 100644 --- a/include/vsprintf.h +++ b/include/vsprintf.h @@ -222,4 +222,16 @@ bool str2long(const char *p, ulong *num); * @hz: Value to convert */ char *strmhz(char *buf, unsigned long hz); + +/** + * str_to_upper() - Convert a string to upper case + * + * This simply uses toupper() on each character of the string. + * + * @in: String to convert (must be large enough to hold the output string) + * @out: Buffer to put converted string + * @len: Number of bytes available in @out (SIZE_MAX for all) + */ +void str_to_upper(const char *in, char *out, size_t len); + #endif diff --git a/lib/strto.c b/lib/strto.c index 606701566f3..3d77115d4d8 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -179,3 +179,11 @@ long trailing_strtol(const char *str) { return trailing_strtoln(str, NULL); } + +void str_to_upper(const char *in, char *out, size_t len) +{ + for (; len > 0 && *in; len--) + *out++ = toupper(*in++); + if (len) + *out = '\0'; +} diff --git a/test/str_ut.c b/test/str_ut.c index fab8de595cb..7c8015050ad 100644 --- a/test/str_ut.c +++ b/test/str_ut.c @@ -19,36 +19,84 @@ static const char str3[] = "0xbI'm sorry you're alive."; /* Declare a new str test */ #define STR_TEST(_name, _flags) UNIT_TEST(_name, _flags, str_test) +static int str_test_upper(struct unit_test_state *uts) +{ + char out[TEST_STR_SIZE]; + + /* Make sure it adds a terminator */ + out[strlen(str1)] = 'a'; + str_to_upper(str1, out, SIZE_MAX); + ut_asserteq_str("I'M SORRY I'M LATE.", out); + + /* In-place operation */ + strcpy(out, str2); + str_to_upper(out, out, SIZE_MAX); + ut_asserteq_str("1099ABNO, DON'T BOTHER APOLOGISING.", out); + + /* Limited length */ + str_to_upper(str1, out, 7); + ut_asserteq_str("I'M SORO, DON'T BOTHER APOLOGISING.", out); + + /* In-place with limited length */ + strcpy(out, str2); + str_to_upper(out, out, 7); + ut_asserteq_str("1099ABNo, don't bother apologising.", out); + + /* Copy an empty string to a buffer with space*/ + out[1] = 0x7f; + str_to_upper("", out, SIZE_MAX); + ut_asserteq('\0', *out); + ut_asserteq(0x7f, out[1]); + + /* Copy an empty string to a buffer with no space*/ + out[0] = 0x7f; + str_to_upper("", out, 0); + ut_asserteq(0x7f, out[0]); + + return 0; +} +STR_TEST(str_test_upper, 0); + static int run_strtoul(struct unit_test_state *uts, const char *str, int base, - ulong expect_val, int expect_endp_offset) + ulong expect_val, int expect_endp_offset, bool upper) { + char out[TEST_STR_SIZE]; char *endp; ulong val; - val = simple_strtoul(str, &endp, base); + strcpy(out, str); + if (upper) + str_to_upper(out, out, -1); + + val = simple_strtoul(out, &endp, base); ut_asserteq(expect_val, val); - ut_asserteq(expect_endp_offset, endp - str); + ut_asserteq(expect_endp_offset, endp - out); return 0; } static int str_simple_strtoul(struct unit_test_state *uts) { - /* Base 10 and base 16 */ - ut_assertok(run_strtoul(uts, str2, 10, 1099, 4)); - ut_assertok(run_strtoul(uts, str2, 16, 0x1099ab, 6)); + int upper; + + /* Check that it is case-insentive */ + for (upper = 0; upper < 2; upper++) { + /* Base 10 and base 16 */ + ut_assertok(run_strtoul(uts, str2, 10, 1099, 4, upper)); + ut_assertok(run_strtoul(uts, str2, 16, 0x1099ab, 6, upper)); - /* Invalid string */ - ut_assertok(run_strtoul(uts, str1, 10, 0, 0)); + /* Invalid string */ + ut_assertok(run_strtoul(uts, str1, 10, 0, 0, upper)); - /* Base 0 */ - ut_assertok(run_strtoul(uts, str1, 0, 0, 0)); - ut_assertok(run_strtoul(uts, str2, 0, 1099, 4)); - ut_assertok(run_strtoul(uts, str3, 0, 0xb, 3)); + /* Base 0 */ + ut_assertok(run_strtoul(uts, str1, 0, 0, 0, upper)); + ut_assertok(run_strtoul(uts, str2, 0, 1099, 4, upper)); + ut_assertok(run_strtoul(uts, str3, 0, 0xb, 3, upper)); - /* Base 2 */ - ut_assertok(run_strtoul(uts, str1, 2, 0, 0)); - ut_assertok(run_strtoul(uts, str2, 2, 2, 2)); + /* Base 2 */ + ut_assertok(run_strtoul(uts, str1, 2, 0, 0, upper)); + ut_assertok(run_strtoul(uts, str2, 2, 2, 2, upper)); + } /* Check endp being NULL */ ut_asserteq(1099, simple_strtoul(str2, NULL, 0)); -- cgit v1.3.1 From 2c2ca207e4ed7def3f3f33ab930e673a45bb3743 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 8 Apr 2020 08:32:58 -0600 Subject: uuid: Use const char * where possible Update the arguments of these functions so they can be called from code which uses constant strings. Signed-off-by: Simon Glass --- include/uuid.h | 8 +++++--- lib/uuid.c | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/include/uuid.h b/include/uuid.h index abcc325eae9..73c5a89ec7c 100644 --- a/include/uuid.h +++ b/include/uuid.h @@ -35,11 +35,13 @@ struct uuid { #define UUID_VARIANT 0x1 int uuid_str_valid(const char *uuid); -int uuid_str_to_bin(char *uuid_str, unsigned char *uuid_bin, int str_format); -void uuid_bin_to_str(unsigned char *uuid_bin, char *uuid_str, int str_format); +int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin, + int str_format); +void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str, + int str_format); #ifdef CONFIG_PARTITION_TYPE_GUID int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin); -int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str); +int uuid_guid_get_str(const unsigned char *guid_bin, char *guid_str); #endif void gen_rand_uuid(unsigned char *uuid_bin); void gen_rand_uuid_str(char *uuid_str, int str_format); diff --git a/lib/uuid.c b/lib/uuid.c index 3d3c7abcaea..c1cb9df6aac 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -121,7 +121,7 @@ int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin) * @param guid_bin - pointer to string with partition type guid [16B] * @param guid_str - pointer to allocated partition type string [7B] */ -int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str) +int uuid_guid_get_str(const unsigned char *guid_bin, char *guid_str) { int i; @@ -143,7 +143,8 @@ int uuid_guid_get_str(unsigned char *guid_bin, char *guid_str) * @param uuid_bin - pointer to allocated array for big endian output [16B] * @str_format - UUID string format: 0 - UUID; 1 - GUID */ -int uuid_str_to_bin(char *uuid_str, unsigned char *uuid_bin, int str_format) +int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin, + int str_format) { uint16_t tmp16; uint32_t tmp32; @@ -194,7 +195,8 @@ int uuid_str_to_bin(char *uuid_str, unsigned char *uuid_bin, int str_format) * @str_format: bit 0: 0 - UUID; 1 - GUID * bit 1: 0 - lower case; 2 - upper case */ -void uuid_bin_to_str(unsigned char *uuid_bin, char *uuid_str, int str_format) +void uuid_bin_to_str(const unsigned char *uuid_bin, char *uuid_str, + int str_format) { const u8 uuid_char_order[UUID_BIN_LEN] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; -- cgit v1.3.1