"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "cmd/setexpr: support concatenation of direct strings"

Heinrich Schuchardt <heinrich.schuchardt@canonical.com> says:

The setexpr.s command allows to concatenate two strings.

According to the description in doc/usage/cmd/setexpr.rst the parameters
value1 and value2 can be either direct values or pointers to a
memory location holding the values.

Unfortunately `setexpr.s <value1> + <value2>` fails if any of the values
is a direct value. $? is set to false.

* Add support for direct values in setexpr.s.
* Correct the unit test for "setexpr.s fred 0".
* Add a new unit test for "setexpr.s fred '1' + '3'" giving '13'.
* Remove invalid memory leak tests

Link: https://lore.kernel.org/r/20250203151029.60265-1-heinrich.schuchardt@canonical.com

+45 -55
+38 -16
cmd/setexpr.c
··· 35 35 }; 36 36 }; 37 37 38 + /** 39 + * arg_set_str() - copy string to expression argument 40 + * 41 + * The string is truncated to 64 KiB plus NUL terminator. 42 + * 43 + * @p: pointer to string 44 + * @argp: pointer to expression argument 45 + * Return: 0 on success, -ENOMEM if out of memory 46 + */ 47 + static int arg_set_str(void *p, struct expr_arg *argp) 48 + { 49 + int len; 50 + char *str; 51 + 52 + /* Maximum string length of 64 KiB plus NUL terminator */ 53 + len = strnlen((char *)p, SZ_64K) + 1; 54 + str = malloc(len); 55 + if (!str) { 56 + printf("Out of memory\n"); 57 + return -ENOMEM; 58 + } 59 + memcpy(str, p, len); 60 + str[len - 1] = '\0'; 61 + argp->sval = str; 62 + return 0; 63 + } 64 + 38 65 static int get_arg(char *s, int w, struct expr_arg *argp) 39 66 { 40 67 struct expr_arg arg; 68 + int ret; 41 69 42 70 /* 43 71 * If the parameter starts with a '*' then assume it is a pointer to ··· 47 75 ulong *p; 48 76 ulong addr; 49 77 ulong val; 50 - int len; 51 - char *str; 52 78 53 79 addr = hextoul(&s[1], NULL); 54 80 switch (w) { ··· 66 92 break; 67 93 case CMD_DATA_SIZE_STR: 68 94 p = map_sysmem(addr, SZ_64K); 69 - 70 - /* Maximum string length of 64KB plus terminator */ 71 - len = strnlen((char *)p, SZ_64K) + 1; 72 - str = malloc(len); 73 - if (!str) { 74 - printf("Out of memory\n"); 75 - return -ENOMEM; 76 - } 77 - memcpy(str, p, len); 78 - str[len - 1] = '\0'; 95 + ret = arg_set_str(p, &arg); 79 96 unmap_sysmem(p); 80 - arg.sval = str; 97 + if (ret) 98 + return ret; 81 99 break; 82 100 case 4: 83 101 p = map_sysmem(addr, sizeof(u32)); ··· 93 111 break; 94 112 } 95 113 } else { 96 - if (w == CMD_DATA_SIZE_STR) 97 - return -EINVAL; 98 - arg.ival = hextoul(s, NULL); 114 + if (w == CMD_DATA_SIZE_STR) { 115 + ret = arg_set_str(s, &arg); 116 + if (ret) 117 + return ret; 118 + } else { 119 + arg.ival = hextoul(s, NULL); 120 + } 99 121 } 100 122 *argp = arg; 101 123
+7 -39
test/cmd/setexpr.c
··· 297 297 /* Test 'setexpr' command with setting strings */ 298 298 static int setexpr_test_str(struct unit_test_state *uts) 299 299 { 300 - ulong start_mem; 301 300 char *buf; 302 301 303 302 buf = map_sysmem(0, BUF_SIZE); 304 303 memset(buf, '\xff', BUF_SIZE); 305 304 306 - /* 307 - * Set 'fred' to the same length as we expect to get below, to avoid a 308 - * new allocation in 'setexpr'. That way we can check for memory leaks. 309 - */ 310 305 ut_assertok(env_set("fred", "x")); 311 - start_mem = ut_check_free(); 312 - strcpy(buf, "hello"); 313 - ut_asserteq(1, run_command("setexpr.s fred 0", 0)); 314 - ut_assertok(ut_check_delta(start_mem)); 306 + ut_asserteq(0, run_command("setexpr.s fred 0", 0)); 307 + ut_asserteq_str("0", env_get("fred")); 315 308 309 + strcpy(buf, "hello"); 316 310 ut_assertok(env_set("fred", "12345")); 317 - start_mem = ut_check_free(); 318 311 ut_assertok(run_command("setexpr.s fred *0", 0)); 319 312 ut_asserteq_str("hello", env_get("fred")); 320 - /* 321 - * This fails in CI at present. 322 - * 323 - * ut_assertok(ut_check_delta(start_mem)); 324 - */ 325 313 326 314 unmap_sysmem(buf); 327 315 ··· 332 320 /* Test 'setexpr' command with concatenating strings */ 333 321 static int setexpr_test_str_oper(struct unit_test_state *uts) 334 322 { 335 - ulong start_mem; 336 323 char *buf; 324 + 325 + /* Test concatenation of strings */ 326 + ut_assertok(run_command("setexpr.s fred '1' + '3'", 0)); 327 + ut_asserteq_str("13", env_get("fred")); 337 328 338 329 buf = map_sysmem(0, BUF_SIZE); 339 330 memset(buf, '\xff', BUF_SIZE); 340 331 strcpy(buf, "hello"); 341 332 strcpy(buf + 0x10, " there"); 342 333 343 - start_mem = ut_check_free(); 344 334 ut_asserteq(1, run_command("setexpr.s fred *0 * *10", 0)); 345 - ut_assertok(ut_check_delta(start_mem)); 346 335 ut_assert_nextline("invalid op"); 347 336 ut_assert_console_end(); 348 337 349 - /* 350 - * Set 'fred' to the same length as we expect to get below, to avoid a 351 - * new allocation in 'setexpr'. That way we can check for memory leaks. 352 - */ 353 338 ut_assertok(env_set("fred", "12345012345")); 354 - start_mem = ut_check_free(); 355 339 ut_assertok(run_command("setexpr.s fred *0 + *10", 0)); 356 340 ut_asserteq_str("hello there", env_get("fred")); 357 - 358 - /* 359 - * This check does not work with sandbox_flattree, apparently due to 360 - * memory allocations in env_set(). 361 - * 362 - * The truetype console produces lots of memory allocations even though 363 - * the LCD display is not visible. But even without these, it does not 364 - * work. 365 - * 366 - * A better test would be for dlmalloc to record the allocs and frees 367 - * for a particular caller, but that is not supported. 368 - * 369 - * For now, drop this test. 370 - * 371 - * ut_assertok(ut_check_delta(start_mem)); 372 - */ 373 341 374 342 unmap_sysmem(buf); 375 343