diff options
| author | Ron Yorston <rmy@pobox.com> | 2025-08-15 09:00:13 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2025-08-15 09:00:13 +0100 |
| commit | 01ff9c492111cf7d51ad074629d6e72bc69fc149 (patch) | |
| tree | 394973e4e5f25dcd638185be75b84430c39ebab2 /libbb | |
| parent | 9a2d9345377d38c428df6d3e0887956d359807ab (diff) | |
| parent | 8bde71eb1502a5cdf186769b47d470038f99bc95 (diff) | |
| download | busybox-w32-01ff9c492111cf7d51ad074629d6e72bc69fc149.tar.gz busybox-w32-01ff9c492111cf7d51ad074629d6e72bc69fc149.tar.bz2 busybox-w32-01ff9c492111cf7d51ad074629d6e72bc69fc149.zip | |
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/c_escape.c | 20 | ||||
| -rw-r--r-- | libbb/concat_path_file.c | 75 | ||||
| -rw-r--r-- | libbb/dump.c | 55 | ||||
| -rw-r--r-- | libbb/getopt32.c | 13 | ||||
| -rw-r--r-- | libbb/hash_md5_sha.c | 72 | ||||
| -rw-r--r-- | libbb/lineedit.c | 2 | ||||
| -rw-r--r-- | libbb/procps.c | 174 | ||||
| -rw-r--r-- | libbb/replace.c | 14 | ||||
| -rw-r--r-- | libbb/yescrypt/alg-sha256.c | 13 |
9 files changed, 305 insertions, 133 deletions
diff --git a/libbb/c_escape.c b/libbb/c_escape.c new file mode 100644 index 000000000..6c109f2e0 --- /dev/null +++ b/libbb/c_escape.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2025 by Denys Vlasenko <vda.linux@googlemail.com> | ||
| 4 | * | ||
| 5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
| 6 | */ | ||
| 7 | //kbuild:lib-y += c_escape.o | ||
| 8 | |||
| 9 | #include "libbb.h" | ||
| 10 | |||
| 11 | const char c_escape_conv_str00[] ALIGN1 = | ||
| 12 | "\\""0""\0" // [0]:00 | ||
| 13 | "\\""a""\0" // [1]:07 | ||
| 14 | "\\""b""\0" // [2]:08 | ||
| 15 | "\\""t""\0" // [3]:09 | ||
| 16 | "\\""n""\0" // [4]:0a | ||
| 17 | "\\""v""\0" // [5]:0b | ||
| 18 | "\\""f""\0" // [6]:0c | ||
| 19 | "\\""r" // [7]:0d | ||
| 20 | ; | ||
diff --git a/libbb/concat_path_file.c b/libbb/concat_path_file.c index 3afb0e3a4..96fcd4a1d 100644 --- a/libbb/concat_path_file.c +++ b/libbb/concat_path_file.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | char* FAST_FUNC concat_path_file(const char *path, const char *filename) | 18 | char* FAST_FUNC concat_path_file(const char *path, const char *filename) |
| 19 | { | 19 | { |
| 20 | #if 0 | ||
| 20 | char *lc; | 21 | char *lc; |
| 21 | 22 | ||
| 22 | if (!path) | 23 | if (!path) |
| @@ -31,4 +32,78 @@ char* FAST_FUNC concat_path_file(const char *path, const char *filename) | |||
| 31 | filename++; | 32 | filename++; |
| 32 | #endif | 33 | #endif |
| 33 | return xasprintf("%s%s%s", path, (lc==NULL ? "/" : ""), filename); | 34 | return xasprintf("%s%s%s", path, (lc==NULL ? "/" : ""), filename); |
| 35 | #else | ||
| 36 | /* ^^^^^^^^^^^ timing of xasprintf-based code above: | ||
| 37 | * real 7.074s | ||
| 38 | * user 0.156s <<< | ||
| 39 | * sys 6.394s | ||
| 40 | * "rm -rf" of a Linux kernel tree from tmpfs (run time still dominated by in-kernel work, though) | ||
| 41 | * real 6.989s | ||
| 42 | * user 0.055s <<< 3 times less CPU used | ||
| 43 | * sys 6.450s | ||
| 44 | * vvvvvvvvvvv timing of open-coded malloc+memcpy code below (+59 bytes): | ||
| 45 | */ | ||
| 46 | char *buf, *p; | ||
| 47 | size_t n1, n2, n3; | ||
| 48 | |||
| 49 | while (*filename == '/') | ||
| 50 | filename++; | ||
| 51 | |||
| 52 | if (!path || !path[0]) | ||
| 53 | return xstrdup(filename); | ||
| 54 | |||
| 55 | n1 = strlen(path); | ||
| 56 | n2 = (path[n1 - 1] != '/'); /* 1: "path has no trailing slash" */ | ||
| 57 | n3 = strlen(filename) + 1; | ||
| 58 | |||
| 59 | buf = xmalloc(n1 + n2 + n3); | ||
| 60 | p = mempcpy(buf, path, n1); | ||
| 61 | if (n2) | ||
| 62 | *p++ = '/'; | ||
| 63 | memcpy(p, filename, n3); | ||
| 64 | return buf; | ||
| 65 | #endif | ||
| 34 | } | 66 | } |
| 67 | |||
| 68 | /* If second component comes from struct dirent, | ||
| 69 | * it's possible to eliminate one strlen() by using name length | ||
| 70 | * provided by kernel in struct dirent. See below. | ||
| 71 | * However, the win seems to be insignificant. | ||
| 72 | */ | ||
| 73 | |||
| 74 | #if 0 | ||
| 75 | |||
| 76 | /* Extract d_namlen from struct dirent */ | ||
| 77 | static size_t get_d_namlen(const struct dirent *de) | ||
| 78 | { | ||
| 79 | #if defined(_DIRENT_HAVE_D_NAMLEN) | ||
| 80 | return de->d_namlen; | ||
| 81 | #elif defined(_DIRENT_HAVE_D_RECLEN) | ||
| 82 | const size_t prefix_sz = offsetof(struct dirent, d_name); | ||
| 83 | return de->d_reclen - prefix_sz; | ||
| 84 | #else | ||
| 85 | return strlen(de->d_name); | ||
| 86 | #endif | ||
| 87 | } | ||
| 88 | |||
| 89 | char* FAST_FUNC concat_path_dirent(const char *path, const struct dirent *de) | ||
| 90 | { | ||
| 91 | char *buf, *p; | ||
| 92 | size_t n1, n2, n3; | ||
| 93 | |||
| 94 | if (!path || !path[0]) | ||
| 95 | return xstrdup(de->d_name); | ||
| 96 | |||
| 97 | n1 = strlen(path); | ||
| 98 | n2 = (path[n1 - 1] != '/'); | ||
| 99 | n3 = get_d_namlen(de) + 1; | ||
| 100 | |||
| 101 | buf = xmalloc(n1 + n2 + n3); | ||
| 102 | p = mempcpy(buf, path, n1); | ||
| 103 | if (n2) | ||
| 104 | *p++ = '/'; | ||
| 105 | memcpy(p, de->d_name, n3); | ||
| 106 | return buf; | ||
| 107 | } | ||
| 108 | |||
| 109 | #endif | ||
diff --git a/libbb/dump.c b/libbb/dump.c index b2abe85af..3dc53d55f 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
| @@ -514,37 +514,52 @@ static void bpad(PR *pr) | |||
| 514 | continue; | 514 | continue; |
| 515 | } | 515 | } |
| 516 | 516 | ||
| 517 | static const char conv_str[] ALIGN1 = | ||
| 518 | "\0" "\\""0""\0" | ||
| 519 | "\007""\\""a""\0" | ||
| 520 | "\b" "\\""b""\0" | ||
| 521 | "\f" "\\""f""\0" | ||
| 522 | "\n" "\\""n""\0" | ||
| 523 | "\r" "\\""r""\0" | ||
| 524 | "\t" "\\""t""\0" | ||
| 525 | "\v" "\\""v""\0" | ||
| 526 | ; | ||
| 527 | |||
| 528 | static void conv_c(PR *pr, unsigned char *p) | 517 | static void conv_c(PR *pr, unsigned char *p) |
| 529 | { | 518 | { |
| 530 | const char *str = conv_str; | 519 | const char *str; |
| 531 | 520 | unsigned char ch; | |
| 532 | do { | 521 | |
| 533 | if (*p == *str) { | 522 | ch = *p; |
| 534 | ++str; | 523 | if (ch == 0 || (ch -= 6, (signed char)ch > 0 && ch <= 7)) { |
| 535 | goto strpr; /* map e.g. '\n' to "\\n" */ | 524 | /* map chars 0,7..13 to "\0","\{a,b,t,n,v,f,r}" */ |
| 536 | } | 525 | str = c_escape_conv_str00 + 3 * ch; |
| 537 | str += 4; | 526 | goto strpr; |
| 538 | } while (*str); | 527 | } |
| 539 | 528 | ||
| 540 | if (isprint_asciionly(*p)) { | 529 | if (isprint_asciionly(*p)) { |
| 541 | *pr->cchar = 'c'; | 530 | *pr->cchar = 'c'; |
| 542 | printf(pr->fmt, *p); | 531 | printf(pr->fmt, *p); |
| 543 | } else { | 532 | } else { |
| 533 | #if defined(__i386__) || defined(__x86_64__) | ||
| 534 | /* Abuse partial register operations */ | ||
| 535 | uint32_t buf; | ||
| 536 | unsigned n = *p; | ||
| 537 | asm ( //00000000 00000000 00000000 aabbbccc | ||
| 538 | "\n shll $10,%%eax" //00000000 000000aa bbbccc00 00000000 | ||
| 539 | "\n shrw $5,%%ax" //00000000 000000aa 00000bbb ccc00000 | ||
| 540 | "\n shrb $5,%%al" //00000000 000000aa 00000bbb 00000ccc | ||
| 541 | "\n shll $8,%%eax" //000000aa 00000bbb 00000ccc 00000000 | ||
| 542 | "\n bswapl %%eax" //00000000 00000ccc 00000bbb 000000aa | ||
| 543 | "\n addl $0x303030,%%eax" | ||
| 544 | "\n" : "=a" (n) | ||
| 545 | : "0" (n) | ||
| 546 | ); | ||
| 547 | buf = n; | ||
| 548 | str = (void*)&buf; | ||
| 549 | #elif 1 | ||
| 544 | char buf[4]; | 550 | char buf[4]; |
| 545 | /* gcc-8.0.1 needs lots of casts to shut up */ | 551 | /* gcc-8.0.1 needs lots of casts to shut up */ |
| 546 | sprintf(buf, "%03o", (unsigned)(uint8_t)*p); | 552 | sprintf(buf, "%03o", (unsigned)(uint8_t)*p); |
| 547 | str = buf; | 553 | str = buf; |
| 554 | #else // use faster version? +20 bytes of code relative to sprintf() method | ||
| 555 | char buf[4]; | ||
| 556 | buf[3] = '\0'; | ||
| 557 | ch = *p; | ||
| 558 | buf[2] = '0' + (ch & 7); ch >>= 3; | ||
| 559 | buf[1] = '0' + (ch & 7); ch >>= 3; | ||
| 560 | buf[0] = '0' + ch; | ||
| 561 | str = buf; | ||
| 562 | #endif | ||
| 548 | strpr: | 563 | strpr: |
| 549 | *pr->cchar = 's'; | 564 | *pr->cchar = 's'; |
| 550 | printf(pr->fmt, str); | 565 | printf(pr->fmt, str); |
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 76d29d5eb..9247588d9 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
| @@ -530,6 +530,7 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |||
| 530 | * "fake" short options, like this one: | 530 | * "fake" short options, like this one: |
| 531 | * wget $'-\203' "Test: test" http://kernel.org/ | 531 | * wget $'-\203' "Test: test" http://kernel.org/ |
| 532 | * (supposed to act as --header, but doesn't) */ | 532 | * (supposed to act as --header, but doesn't) */ |
| 533 | next_opt: | ||
| 533 | #if ENABLE_LONG_OPTS | 534 | #if ENABLE_LONG_OPTS |
| 534 | while ((c = getopt_long(argc, argv, applet_opts, | 535 | while ((c = getopt_long(argc, argv, applet_opts, |
| 535 | long_options, NULL)) != -1) { | 536 | long_options, NULL)) != -1) { |
| @@ -544,8 +545,16 @@ vgetopt32(char **argv, const char *applet_opts, const char *applet_long_options, | |||
| 544 | * but we construct long opts so that flag | 545 | * but we construct long opts so that flag |
| 545 | * is always NULL (see above) */ | 546 | * is always NULL (see above) */ |
| 546 | if (on_off->opt_char == '\0' /* && c != '\0' */) { | 547 | if (on_off->opt_char == '\0' /* && c != '\0' */) { |
| 547 | /* c is probably '?' - "bad option" */ | 548 | /* We reached the end of complementary[] and did not find -c */ |
| 548 | goto error; | 549 | if (c == '?') /* getopt says: "bad option, or option has no required argument" */ |
| 550 | goto error; | ||
| 551 | /* if there were options beyond 32 bits (example: ls), | ||
| 552 | * they got no complementary[] slot, and no result bit. | ||
| 553 | * IOW: they must be "accept but ignore" options. | ||
| 554 | * For them, we end up here. | ||
| 555 | */ | ||
| 556 | //bb_error_msg("ignored option '%c', skipping", c); | ||
| 557 | goto next_opt; | ||
| 549 | } | 558 | } |
| 550 | } | 559 | } |
| 551 | if (flags & on_off->incongruously) | 560 | if (flags & on_off->incongruously) |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index 22dd890bf..fd56d831b 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | #define STR1(s) #s | 11 | #define STR1(s) #s |
| 12 | #define STR(s) STR1(s) | 12 | #define STR(s) STR1(s) |
| 13 | 13 | ||
| 14 | #define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA) | 14 | #define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_SHA384SUM || ENABLE_USE_BB_CRYPT_SHA) |
| 15 | 15 | ||
| 16 | #if ENABLE_FEATURE_USE_CNG_API | 16 | #if ENABLE_FEATURE_USE_CNG_API |
| 17 | # include <windows.h> | 17 | # include <windows.h> |
| @@ -21,6 +21,7 @@ | |||
| 21 | # define BCRYPT_MD5_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000021) | 21 | # define BCRYPT_MD5_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000021) |
| 22 | # define BCRYPT_SHA1_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000031) | 22 | # define BCRYPT_SHA1_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000031) |
| 23 | # define BCRYPT_SHA256_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000041) | 23 | # define BCRYPT_SHA256_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000041) |
| 24 | # define BCRYPT_SHA384_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000051) | ||
| 24 | # define BCRYPT_SHA512_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000061) | 25 | # define BCRYPT_SHA512_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000061) |
| 25 | 26 | ||
| 26 | /* Initialize structure containing state of computation. | 27 | /* Initialize structure containing state of computation. |
| @@ -61,9 +62,18 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | |||
| 61 | generic_init(ctx, BCRYPT_SHA256_ALG_HANDLE); | 62 | generic_init(ctx, BCRYPT_SHA256_ALG_HANDLE); |
| 62 | } | 63 | } |
| 63 | 64 | ||
| 64 | #if NEED_SHA512 | 65 | #if ENABLE_SHA384SUM |
| 65 | /* Initialize structure containing state of computation. | 66 | /* Initialize structure containing state of computation. |
| 66 | (FIPS 180-2:5.3.3) */ | 67 | (FIPS 180-2:5.3.3) */ |
| 68 | void FAST_FUNC sha384_begin(sha384_ctx_t *ctx) | ||
| 69 | { | ||
| 70 | generic_init(ctx, BCRYPT_SHA384_ALG_HANDLE); | ||
| 71 | } | ||
| 72 | #endif /* ENABLE_SHA384SUM */ | ||
| 73 | |||
| 74 | #if NEED_SHA512 | ||
| 75 | /* Initialize structure containing state of computation. | ||
| 76 | (FIPS 180-2:5.3.4) */ | ||
| 67 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | 77 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) |
| 68 | { | 78 | { |
| 69 | generic_init(ctx, BCRYPT_SHA512_ALG_HANDLE); | 79 | generic_init(ctx, BCRYPT_SHA512_ALG_HANDLE); |
| @@ -1109,7 +1119,7 @@ static const sha_K_int sha_K[] ALIGN8 = { | |||
| 1109 | K(0x84c87814a1f0ab72ULL), K(0x8cc702081a6439ecULL), | 1119 | K(0x84c87814a1f0ab72ULL), K(0x8cc702081a6439ecULL), |
| 1110 | K(0x90befffa23631e28ULL), K(0xa4506cebde82bde9ULL), | 1120 | K(0x90befffa23631e28ULL), K(0xa4506cebde82bde9ULL), |
| 1111 | K(0xbef9a3f7b2c67915ULL), K(0xc67178f2e372532bULL), | 1121 | K(0xbef9a3f7b2c67915ULL), K(0xc67178f2e372532bULL), |
| 1112 | #if NEED_SHA512 /* [64]+ are used for sha512 only */ | 1122 | #if NEED_SHA512 /* [64]+ are used for sha384 and sha512 only */ |
| 1113 | K(0xca273eceea26619cULL), K(0xd186b8c721c0c207ULL), | 1123 | K(0xca273eceea26619cULL), K(0xd186b8c721c0c207ULL), |
| 1114 | K(0xeada7dd6cde0eb1eULL), K(0xf57d4f7fee6ed178ULL), | 1124 | K(0xeada7dd6cde0eb1eULL), K(0xf57d4f7fee6ed178ULL), |
| 1115 | K(0x06f067aa72176fbaULL), K(0x0a637dc5a2c898a6ULL), | 1125 | K(0x06f067aa72176fbaULL), K(0x0a637dc5a2c898a6ULL), |
| @@ -1306,11 +1316,20 @@ static const uint32_t init512_lo[] ALIGN4 = { | |||
| 1306 | 0x137e2179, | 1316 | 0x137e2179, |
| 1307 | }; | 1317 | }; |
| 1308 | #endif /* NEED_SHA512 */ | 1318 | #endif /* NEED_SHA512 */ |
| 1309 | 1319 | #if ENABLE_SHA384SUM | |
| 1310 | // Note: SHA-384 is identical to SHA-512, except that initial hash values are | 1320 | static const uint64_t init384[] ALIGN8 = { |
| 1311 | // 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939, | 1321 | 0, |
| 1312 | // 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4, | 1322 | 0, |
| 1313 | // and the output is constructed by omitting last two 64-bit words of it. | 1323 | 0xcbbb9d5dc1059ed8, |
| 1324 | 0x629a292a367cd507, | ||
| 1325 | 0x9159015a3070dd17, | ||
| 1326 | 0x152fecd8f70e5939, | ||
| 1327 | 0x67332667ffc00b31, | ||
| 1328 | 0x8eb44a8768581511, | ||
| 1329 | 0xdb0c2e0d64f98fa7, | ||
| 1330 | 0x47b5481dbefa4fa4, | ||
| 1331 | }; | ||
| 1332 | #endif | ||
| 1314 | 1333 | ||
| 1315 | /* Initialize structure containing state of computation. | 1334 | /* Initialize structure containing state of computation. |
| 1316 | (FIPS 180-2:5.3.2) */ | 1335 | (FIPS 180-2:5.3.2) */ |
| @@ -1332,9 +1351,19 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | |||
| 1332 | #endif | 1351 | #endif |
| 1333 | } | 1352 | } |
| 1334 | 1353 | ||
| 1335 | #if NEED_SHA512 | 1354 | #if ENABLE_SHA384SUM |
| 1336 | /* Initialize structure containing state of computation. | 1355 | /* Initialize structure containing state of computation. |
| 1337 | (FIPS 180-2:5.3.3) */ | 1356 | (FIPS 180-2:5.3.3) */ |
| 1357 | void FAST_FUNC sha384_begin(sha512_ctx_t *ctx) | ||
| 1358 | { | ||
| 1359 | memcpy(&ctx->total64, init384, sizeof(init384)); | ||
| 1360 | /*ctx->total64[0] = ctx->total64[1] = 0; - already done */ | ||
| 1361 | } | ||
| 1362 | #endif | ||
| 1363 | |||
| 1364 | #if NEED_SHA512 | ||
| 1365 | /* Initialize structure containing state of computation. | ||
| 1366 | (FIPS 180-2:5.3.4) */ | ||
| 1338 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | 1367 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) |
| 1339 | { | 1368 | { |
| 1340 | int i; | 1369 | int i; |
| @@ -1409,7 +1438,7 @@ unsigned FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | |||
| 1409 | } | 1438 | } |
| 1410 | 1439 | ||
| 1411 | #if NEED_SHA512 | 1440 | #if NEED_SHA512 |
| 1412 | unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | 1441 | static unsigned FAST_FUNC sha512384_end(sha512_ctx_t *ctx, void *resbuf, unsigned outsize) |
| 1413 | { | 1442 | { |
| 1414 | unsigned bufpos = ctx->total64[0] & 127; | 1443 | unsigned bufpos = ctx->total64[0] & 127; |
| 1415 | 1444 | ||
| @@ -1440,12 +1469,22 @@ unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
| 1440 | for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) | 1469 | for (i = 0; i < ARRAY_SIZE(ctx->hash); ++i) |
| 1441 | ctx->hash[i] = SWAP_BE64(ctx->hash[i]); | 1470 | ctx->hash[i] = SWAP_BE64(ctx->hash[i]); |
| 1442 | } | 1471 | } |
| 1443 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); | 1472 | memcpy(resbuf, ctx->hash, outsize); |
| 1444 | return sizeof(ctx->hash); | 1473 | return outsize; |
| 1474 | } | ||
| 1475 | unsigned FAST_FUNC sha512_end(sha384_ctx_t *ctx, void *resbuf) | ||
| 1476 | { | ||
| 1477 | return sha512384_end(ctx, resbuf, SHA512_OUTSIZE); | ||
| 1445 | } | 1478 | } |
| 1446 | #endif /* NEED_SHA512 */ | 1479 | #endif /* NEED_SHA512 */ |
| 1447 | #endif /* !ENABLE_FEATURE_USE_CNG_API */ | ||
| 1448 | 1480 | ||
| 1481 | #if ENABLE_SHA384SUM | ||
| 1482 | unsigned FAST_FUNC sha384_end(sha384_ctx_t *ctx, void *resbuf) | ||
| 1483 | { | ||
| 1484 | return sha512384_end(ctx, resbuf, SHA384_OUTSIZE); | ||
| 1485 | } | ||
| 1486 | #endif | ||
| 1487 | #endif /* !ENABLE_FEATURE_USE_CNG_API */ | ||
| 1449 | 1488 | ||
| 1450 | /* | 1489 | /* |
| 1451 | * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, | 1490 | * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, |
| @@ -1982,6 +2021,8 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | |||
| 1982 | 2021 | ||
| 1983 | unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) | 2022 | unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) |
| 1984 | { | 2023 | { |
| 2024 | unsigned hash_len; | ||
| 2025 | |||
| 1985 | /* Padding */ | 2026 | /* Padding */ |
| 1986 | uint8_t *buf = (uint8_t*)ctx->state; | 2027 | uint8_t *buf = (uint8_t*)ctx->state; |
| 1987 | /* | 2028 | /* |
| @@ -2004,6 +2045,7 @@ unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) | |||
| 2004 | sha3_process_block72(ctx->state); | 2045 | sha3_process_block72(ctx->state); |
| 2005 | 2046 | ||
| 2006 | /* Output */ | 2047 | /* Output */ |
| 2007 | memcpy(resbuf, ctx->state, 64); | 2048 | hash_len = (1600/8 - ctx->input_block_bytes) / 2; |
| 2008 | return 64; | 2049 | memcpy(resbuf, ctx->state, hash_len); |
| 2050 | return hash_len; | ||
| 2009 | } | 2051 | } |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index c8a0f37fe..77207a427 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
| @@ -1754,7 +1754,7 @@ void FAST_FUNC save_history(line_input_t *st) | |||
| 1754 | FILE *fp; | 1754 | FILE *fp; |
| 1755 | 1755 | ||
| 1756 | /* bash compat: HISTFILE="" disables history saving */ | 1756 | /* bash compat: HISTFILE="" disables history saving */ |
| 1757 | if (!st || !st->hist_file || !state->hist_file[0]) | 1757 | if (!st || !st->hist_file || !st->hist_file[0]) |
| 1758 | return; | 1758 | return; |
| 1759 | if (st->cnt_history <= st->cnt_history_in_file) | 1759 | if (st->cnt_history <= st->cnt_history_in_file) |
| 1760 | return; /* no new entries were added */ | 1760 | return; /* no new entries were added */ |
diff --git a/libbb/procps.c b/libbb/procps.c index 8c9cac125..c751100bc 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
| @@ -110,7 +110,7 @@ void FAST_FUNC free_procps_scan(procps_status_t* sp) | |||
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | #if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP | 112 | #if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP |
| 113 | static unsigned long long fast_strtoull_16(char **endptr) | 113 | unsigned long long FAST_FUNC fast_strtoull_16(char **endptr) |
| 114 | { | 114 | { |
| 115 | unsigned char c; | 115 | unsigned char c; |
| 116 | char *str = *endptr; | 116 | char *str = *endptr; |
| @@ -131,7 +131,7 @@ static unsigned long long fast_strtoull_16(char **endptr) | |||
| 131 | 131 | ||
| 132 | #if ENABLE_FEATURE_FAST_TOP || ENABLE_FEATURE_TOPMEM || ENABLE_PMAP | 132 | #if ENABLE_FEATURE_FAST_TOP || ENABLE_FEATURE_TOPMEM || ENABLE_PMAP |
| 133 | /* We cut a lot of corners here for speed */ | 133 | /* We cut a lot of corners here for speed */ |
| 134 | static unsigned long fast_strtoul_10(char **endptr) | 134 | unsigned long FAST_FUNC fast_strtoul_10(char **endptr) |
| 135 | { | 135 | { |
| 136 | unsigned char c; | 136 | unsigned char c; |
| 137 | char *str = *endptr; | 137 | char *str = *endptr; |
| @@ -144,6 +144,24 @@ static unsigned long fast_strtoul_10(char **endptr) | |||
| 144 | *endptr = str + 1; /* We skip trailing space! */ | 144 | *endptr = str + 1; /* We skip trailing space! */ |
| 145 | return n; | 145 | return n; |
| 146 | } | 146 | } |
| 147 | # if LONG_MAX < LLONG_MAX | ||
| 148 | /* For VSZ, which can be very large */ | ||
| 149 | static unsigned long long fast_strtoull_10(char **endptr) | ||
| 150 | { | ||
| 151 | unsigned char c; | ||
| 152 | char *str = *endptr; | ||
| 153 | unsigned long long n = *str - '0'; | ||
| 154 | |||
| 155 | /* Need to stop on both ' ' and '\n' */ | ||
| 156 | while ((c = *++str) > ' ') | ||
| 157 | n = n*10 + (c - '0'); | ||
| 158 | |||
| 159 | *endptr = str + 1; /* We skip trailing space! */ | ||
| 160 | return n; | ||
| 161 | } | ||
| 162 | # else | ||
| 163 | # define fast_strtoull_10(endptr) fast_strtoul_10(endptr) | ||
| 164 | # endif | ||
| 147 | 165 | ||
| 148 | # if ENABLE_FEATURE_FAST_TOP | 166 | # if ENABLE_FEATURE_FAST_TOP |
| 149 | static long fast_strtol_10(char **endptr) | 167 | static long fast_strtol_10(char **endptr) |
| @@ -156,7 +174,7 @@ static long fast_strtol_10(char **endptr) | |||
| 156 | } | 174 | } |
| 157 | # endif | 175 | # endif |
| 158 | 176 | ||
| 159 | static char *skip_fields(char *str, int count) | 177 | char* FAST_FUNC skip_fields(char *str, int count) |
| 160 | { | 178 | { |
| 161 | do { | 179 | do { |
| 162 | while (*str++ != ' ') | 180 | while (*str++ != ' ') |
| @@ -167,35 +185,25 @@ static char *skip_fields(char *str, int count) | |||
| 167 | } | 185 | } |
| 168 | #endif | 186 | #endif |
| 169 | 187 | ||
| 170 | #if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP | 188 | #if ENABLE_FEATURE_TOPMEM |
| 171 | static char* skip_whitespace_if_prefixed_with(char *buf, const char *prefix) | 189 | static NOINLINE void procps_read_smaps(pid_t pid, procps_status_t *sp) |
| 172 | { | 190 | { |
| 173 | char *tp = is_prefixed_with(buf, prefix); | 191 | // There is A LOT of /proc/PID/smaps data on a big system. |
| 174 | if (tp) { | 192 | // Optimize this for speed, makes "top -m" faster. |
| 175 | tp = skip_whitespace(tp); | 193 | //TODO large speedup: |
| 176 | } | 194 | //read /proc/PID/smaps_rollup (cumulative stats of all mappings, much faster) |
| 177 | return tp; | 195 | //and /proc/PID/maps to get mapped_ro and mapped_rw (IOW: VSZ,VSZRW) |
| 178 | } | ||
| 179 | 196 | ||
| 180 | int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | ||
| 181 | void (*cb)(struct smaprec *, void *), void *data) | ||
| 182 | { | ||
| 183 | FILE *file; | 197 | FILE *file; |
| 184 | struct smaprec currec; | ||
| 185 | char filename[sizeof("/proc/%u/smaps") + sizeof(int)*3]; | 198 | char filename[sizeof("/proc/%u/smaps") + sizeof(int)*3]; |
| 186 | char buf[PROCPS_BUFSIZE]; | 199 | char buf[PROCPS_BUFSIZE]; |
| 187 | #if !ENABLE_PMAP | ||
| 188 | void (*cb)(struct smaprec *, void *) = NULL; | ||
| 189 | void *data = NULL; | ||
| 190 | #endif | ||
| 191 | 200 | ||
| 192 | sprintf(filename, "/proc/%u/smaps", (int)pid); | 201 | sprintf(filename, "/proc/%u/smaps", (int)pid); |
| 193 | 202 | ||
| 194 | file = fopen_for_read(filename); | 203 | file = fopen_for_read(filename); |
| 195 | if (!file) | 204 | if (!file) |
| 196 | return 1; | 205 | return; |
| 197 | 206 | ||
| 198 | memset(&currec, 0, sizeof(currec)); | ||
| 199 | while (fgets(buf, PROCPS_BUFSIZE, file)) { | 207 | while (fgets(buf, PROCPS_BUFSIZE, file)) { |
| 200 | // Each mapping datum has this form: | 208 | // Each mapping datum has this form: |
| 201 | // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME | 209 | // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME |
| @@ -203,80 +211,53 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | |||
| 203 | // Rss: nnn kB | 211 | // Rss: nnn kB |
| 204 | // ..... | 212 | // ..... |
| 205 | 213 | ||
| 206 | char *tp, *p; | 214 | char *tp; |
| 207 | 215 | ||
| 216 | if (buf[0] == 'S' || buf[0] == 'P') { | ||
| 208 | #define SCAN(S, X) \ | 217 | #define SCAN(S, X) \ |
| 209 | if ((tp = skip_whitespace_if_prefixed_with(buf, S)) != NULL) { \ | 218 | if (memcmp(buf, S, sizeof(S)-1) == 0) { \ |
| 210 | total->X += currec.X = fast_strtoul_10(&tp); \ | 219 | tp = skip_whitespace(buf + sizeof(S)-1); \ |
| 211 | continue; \ | 220 | sp->X += fast_strtoul_10(&tp); \ |
| 212 | } | 221 | continue; \ |
| 213 | if (cb) { | 222 | } |
| 214 | SCAN("Pss:" , smap_pss ); | 223 | SCAN("Private_Dirty:", private_dirty) |
| 215 | SCAN("Swap:" , smap_swap ); | 224 | SCAN("Private_Clean:", private_clean) |
| 216 | } | 225 | SCAN("Shared_Dirty:" , shared_dirty ) |
| 217 | SCAN("Private_Dirty:", private_dirty); | 226 | SCAN("Shared_Clean:" , shared_clean ) |
| 218 | SCAN("Private_Clean:", private_clean); | ||
| 219 | SCAN("Shared_Dirty:" , shared_dirty ); | ||
| 220 | SCAN("Shared_Clean:" , shared_clean ); | ||
| 221 | #undef SCAN | 227 | #undef SCAN |
| 228 | } | ||
| 222 | tp = strchr(buf, '-'); | 229 | tp = strchr(buf, '-'); |
| 223 | if (tp) { | 230 | if (tp) { |
| 224 | // We reached next mapping - the line of this form: | 231 | // We reached next mapping - the line of this form: |
| 225 | // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME | 232 | // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME |
| 226 | 233 | ||
| 227 | if (cb) { | 234 | char *rwx; |
| 228 | /* If we have a previous record, there's nothing more | 235 | unsigned long sz; |
| 229 | * for it, call the callback and clear currec | ||
| 230 | */ | ||
| 231 | if (currec.smap_size) | ||
| 232 | cb(&currec, data); | ||
| 233 | free(currec.smap_name); | ||
| 234 | } | ||
| 235 | memset(&currec, 0, sizeof(currec)); | ||
| 236 | 236 | ||
| 237 | *tp = ' '; | 237 | *tp = ' '; |
| 238 | tp = buf; | 238 | tp = buf; |
| 239 | currec.smap_start = fast_strtoull_16(&tp); | 239 | sz = fast_strtoull_16(&tp); // start |
| 240 | currec.smap_size = (fast_strtoull_16(&tp) - currec.smap_start) >> 10; | 240 | sz = (fast_strtoull_16(&tp) - sz) >> 10; // end - start |
| 241 | 241 | // tp -> "rw-s" string | |
| 242 | strncpy(currec.smap_mode, tp, sizeof(currec.smap_mode)-1); | 242 | rwx = tp; |
| 243 | |||
| 244 | // skipping "rw-s FILEOFS M:m INODE " | 243 | // skipping "rw-s FILEOFS M:m INODE " |
| 245 | tp = skip_whitespace(skip_fields(tp, 4)); | 244 | tp = skip_whitespace(skip_fields(tp, 4)); |
| 246 | // filter out /dev/something (something != zero) | 245 | // if not a device memory mapped... |
| 247 | if (!is_prefixed_with(tp, "/dev/") || strcmp(tp, "/dev/zero\n") == 0) { | 246 | if (memcmp(tp, "/dev/", 5) != 0 // not "/dev/something" |
| 248 | if (currec.smap_mode[1] == 'w') { | 247 | || strcmp(tp + 5, "zero\n") == 0 // or is "/dev/zero" (which isn't a device) |
| 249 | currec.mapped_rw = currec.smap_size; | 248 | ) { |
| 250 | total->mapped_rw += currec.smap_size; | 249 | if (rwx[1] == 'w') |
| 251 | } else if (currec.smap_mode[1] == '-') { | 250 | sp->mapped_rw += sz; |
| 252 | currec.mapped_ro = currec.smap_size; | 251 | else if (rwx[0] == 'r' || rwx[2] == 'x') |
| 253 | total->mapped_ro += currec.smap_size; | 252 | sp->mapped_ro += sz; |
| 254 | } | 253 | // else: seen "---p" mappings (mmap guard gaps?), |
| 254 | // do NOT account these as VSZ, they aren't really | ||
| 255 | } | 255 | } |
| 256 | |||
| 257 | if (strcmp(tp, "[stack]\n") == 0) | 256 | if (strcmp(tp, "[stack]\n") == 0) |
| 258 | total->stack += currec.smap_size; | 257 | sp->stack += sz; |
| 259 | if (cb) { | ||
| 260 | p = skip_non_whitespace(tp); | ||
| 261 | if (p == tp) { | ||
| 262 | currec.smap_name = xstrdup(" [ anon ]"); | ||
| 263 | } else { | ||
| 264 | *p = '\0'; | ||
| 265 | currec.smap_name = xstrdup(tp); | ||
| 266 | } | ||
| 267 | } | ||
| 268 | total->smap_size += currec.smap_size; | ||
| 269 | } | 258 | } |
| 270 | } | 259 | } |
| 271 | fclose(file); | 260 | fclose(file); |
| 272 | |||
| 273 | if (cb) { | ||
| 274 | if (currec.smap_size) | ||
| 275 | cb(&currec, data); | ||
| 276 | free(currec.smap_name); | ||
| 277 | } | ||
| 278 | |||
| 279 | return 0; | ||
| 280 | } | 261 | } |
| 281 | #endif | 262 | #endif |
| 282 | 263 | ||
| @@ -371,7 +352,8 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
| 371 | char *cp, *comm1; | 352 | char *cp, *comm1; |
| 372 | int tty; | 353 | int tty; |
| 373 | #if !ENABLE_FEATURE_FAST_TOP | 354 | #if !ENABLE_FEATURE_FAST_TOP |
| 374 | unsigned long vsz, rss; | 355 | unsigned long long vsz; |
| 356 | unsigned long rss; | ||
| 375 | #endif | 357 | #endif |
| 376 | /* see proc(5) for some details on this */ | 358 | /* see proc(5) for some details on this */ |
| 377 | strcpy(filename_tail, "stat"); | 359 | strcpy(filename_tail, "stat"); |
| @@ -397,7 +379,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
| 397 | "%ld " /* nice */ | 379 | "%ld " /* nice */ |
| 398 | "%*s %*s " /* timeout, it_real_value */ | 380 | "%*s %*s " /* timeout, it_real_value */ |
| 399 | "%lu " /* start_time */ | 381 | "%lu " /* start_time */ |
| 400 | "%lu " /* vsize */ | 382 | "%llu " /* vsize - can be very large */ |
| 401 | "%lu " /* rss */ | 383 | "%lu " /* rss */ |
| 402 | # if ENABLE_FEATURE_TOP_SMP_PROCESS | 384 | # if ENABLE_FEATURE_TOP_SMP_PROCESS |
| 403 | "%*s %*s %*s %*s %*s %*s " /*rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */ | 385 | "%*s %*s %*s %*s %*s %*s " /*rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */ |
| @@ -450,7 +432,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
| 450 | cp = skip_fields(cp, 2); /* timeout, it_real_value */ | 432 | cp = skip_fields(cp, 2); /* timeout, it_real_value */ |
| 451 | sp->start_time = fast_strtoul_10(&cp); | 433 | sp->start_time = fast_strtoul_10(&cp); |
| 452 | /* vsz is in bytes and we want kb */ | 434 | /* vsz is in bytes and we want kb */ |
| 453 | sp->vsz = fast_strtoul_10(&cp) >> 10; | 435 | sp->vsz = fast_strtoull_10(&cp) >> 10; |
| 454 | /* vsz is in bytes but rss is in *PAGES*! Can you believe that? */ | 436 | /* vsz is in bytes but rss is in *PAGES*! Can you believe that? */ |
| 455 | sp->rss = fast_strtoul_10(&cp) << sp->shift_pages_to_kb; | 437 | sp->rss = fast_strtoul_10(&cp) << sp->shift_pages_to_kb; |
| 456 | # if ENABLE_FEATURE_TOP_SMP_PROCESS | 438 | # if ENABLE_FEATURE_TOP_SMP_PROCESS |
| @@ -484,7 +466,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
| 484 | 466 | ||
| 485 | #if ENABLE_FEATURE_TOPMEM | 467 | #if ENABLE_FEATURE_TOPMEM |
| 486 | if (flags & PSSCAN_SMAPS) | 468 | if (flags & PSSCAN_SMAPS) |
| 487 | procps_read_smaps(pid, &sp->smaps, NULL, NULL); | 469 | procps_read_smaps(pid, sp); |
| 488 | #endif /* TOPMEM */ | 470 | #endif /* TOPMEM */ |
| 489 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS | 471 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS |
| 490 | if (flags & PSSCAN_RUIDGID) { | 472 | if (flags & PSSCAN_RUIDGID) { |
| @@ -567,36 +549,45 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
| 567 | return sp; | 549 | return sp; |
| 568 | } | 550 | } |
| 569 | 551 | ||
| 570 | void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) | 552 | int FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) |
| 571 | { | 553 | { |
| 572 | int sz; | 554 | int sz; |
| 573 | char filename[sizeof("/proc/%u/cmdline") + sizeof(int)*3]; | 555 | char filename[sizeof("/proc/%u/cmdline") + sizeof(int)*3]; |
| 574 | 556 | ||
| 575 | sprintf(filename, "/proc/%u/cmdline", pid); | 557 | sprintf(filename, "/proc/%u/cmdline", pid); |
| 576 | sz = open_read_close(filename, buf, col - 1); | 558 | sz = open_read_close(filename, buf, col - 1); |
| 559 | if (sz < 0) | ||
| 560 | return sz; | ||
| 577 | if (sz > 0) { | 561 | if (sz > 0) { |
| 578 | const char *base; | 562 | const char *program_basename; |
| 579 | int comm_len; | 563 | int comm_len; |
| 580 | 564 | ||
| 581 | buf[sz] = '\0'; | 565 | buf[sz] = '\0'; |
| 582 | while (--sz >= 0 && buf[sz] == '\0') | 566 | while (--sz >= 0 && buf[sz] == '\0') |
| 583 | continue; | 567 | continue; |
| 584 | /* Prevent basename("process foo/bar") = "bar" */ | 568 | |
| 585 | strchrnul(buf, ' ')[0] = '\0'; | 569 | /* Find "program" in "[-][/PATH/TO/]program" */ |
| 586 | base = bb_basename(buf); /* before we replace argv0's NUL with space */ | 570 | strchrnul(buf, ' ')[0] = '\0'; /* prevent basename("program foo/bar") = "bar" */ |
| 571 | program_basename = bb_basename(buf[0] == '-' ? buf + 1 : buf); | ||
| 572 | /* ^^^ note: must do it *before* replacing argv0's NUL with space */ | ||
| 573 | |||
| 574 | /* Prevent stuff like this: | ||
| 575 | * echo 'sleep 999; exit' >`printf '\ec'`; sh ?c | ||
| 576 | * messing up top and ps output (or worse). | ||
| 577 | * This also replaces NULs with spaces, converting | ||
| 578 | * list of NUL-strings into one string. | ||
| 579 | */ | ||
| 587 | while (sz >= 0) { | 580 | while (sz >= 0) { |
| 588 | if ((unsigned char)(buf[sz]) < ' ') | 581 | if ((unsigned char)(buf[sz]) < ' ') |
| 589 | buf[sz] = ' '; | 582 | buf[sz] = ' '; |
| 590 | sz--; | 583 | sz--; |
| 591 | } | 584 | } |
| 592 | if (base[0] == '-') /* "-sh" (login shell)? */ | ||
| 593 | base++; | ||
| 594 | 585 | ||
| 595 | /* If comm differs from argv0, prepend "{comm} ". | 586 | /* If comm differs from argv0, prepend "{comm} ". |
| 596 | * It allows to see thread names set by prctl(PR_SET_NAME). | 587 | * It allows to see thread names set by prctl(PR_SET_NAME). |
| 597 | */ | 588 | */ |
| 598 | if (!comm) | 589 | if (!comm) |
| 599 | return; | 590 | return 0; |
| 600 | comm_len = strlen(comm); | 591 | comm_len = strlen(comm); |
| 601 | /* Why compare up to comm_len, not COMM_LEN-1? | 592 | /* Why compare up to comm_len, not COMM_LEN-1? |
| 602 | * Well, some processes rewrite argv, and use _spaces_ there | 593 | * Well, some processes rewrite argv, and use _spaces_ there |
| @@ -604,19 +595,20 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) | |||
| 604 | * I prefer to still treat argv0 "process foo bar" | 595 | * I prefer to still treat argv0 "process foo bar" |
| 605 | * as 'equal' to comm "process". | 596 | * as 'equal' to comm "process". |
| 606 | */ | 597 | */ |
| 607 | if (strncmp(base, comm, comm_len) != 0) { | 598 | if (strncmp(program_basename, comm, comm_len) != 0) { |
| 608 | comm_len += 3; | 599 | comm_len += 3; |
| 609 | if (col > comm_len) | 600 | if (col > comm_len) |
| 610 | memmove(buf + comm_len, buf, col - comm_len); | 601 | memmove(buf + comm_len, buf, col - comm_len); |
| 611 | snprintf(buf, col, "{%s}", comm); | 602 | snprintf(buf, col, "{%s}", comm); |
| 612 | if (col <= comm_len) | 603 | if (col <= comm_len) |
| 613 | return; | 604 | return 0; |
| 614 | buf[comm_len - 1] = ' '; | 605 | buf[comm_len - 1] = ' '; |
| 615 | buf[col - 1] = '\0'; | 606 | buf[col - 1] = '\0'; |
| 616 | } | 607 | } |
| 617 | } else { | 608 | } else { |
| 618 | snprintf(buf, col, "[%s]", comm ? comm : "?"); | 609 | snprintf(buf, col, "[%s]", comm ? comm : "?"); |
| 619 | } | 610 | } |
| 611 | return 0; | ||
| 620 | } | 612 | } |
| 621 | 613 | ||
| 622 | #endif /* ENABLE_PLATFORM_MINGW32 */ | 614 | #endif /* ENABLE_PLATFORM_MINGW32 */ |
diff --git a/libbb/replace.c b/libbb/replace.c index 6183d3e6f..bc26b04cc 100644 --- a/libbb/replace.c +++ b/libbb/replace.c | |||
| @@ -46,3 +46,17 @@ char* FAST_FUNC xmalloc_substitute_string(const char *src, int count, const char | |||
| 46 | //dbg_msg("subst9:'%s'", buf); | 46 | //dbg_msg("subst9:'%s'", buf); |
| 47 | return buf; | 47 | return buf; |
| 48 | } | 48 | } |
| 49 | |||
| 50 | #if 0 /* inlined in libbb.h */ | ||
| 51 | /* Returns strlen as a bonus */ | ||
| 52 | size_t FAST_FUNC replace_char(char *str, char from, char to) | ||
| 53 | { | ||
| 54 | char *p = str; | ||
| 55 | while (*p) { | ||
| 56 | if (*p == from) | ||
| 57 | *p = to; | ||
| 58 | p++; | ||
| 59 | } | ||
| 60 | return p - str; | ||
| 61 | } | ||
| 62 | #endif | ||
diff --git a/libbb/yescrypt/alg-sha256.c b/libbb/yescrypt/alg-sha256.c index 20e8d1ee4..dc748c968 100644 --- a/libbb/yescrypt/alg-sha256.c +++ b/libbb/yescrypt/alg-sha256.c | |||
| @@ -47,9 +47,12 @@ PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, | |||
| 47 | 47 | ||
| 48 | /* Iterate through the blocks. */ | 48 | /* Iterate through the blocks. */ |
| 49 | for (i = 0; dkLen != 0; ) { | 49 | for (i = 0; dkLen != 0; ) { |
| 50 | uint64_t U[32 / 8]; | 50 | long U[32 / sizeof(long)]; |
| 51 | uint64_t T[32 / 8]; | 51 | long T[32 / sizeof(long)]; |
| 52 | uint64_t j; | 52 | // Do not make these ^^ uint64_t[]. Keep them long[]. |
| 53 | // Even though the XORing loop below is optimized out, | ||
| 54 | // gcc is not smart enough to realize that 64-bit alignment of the stack | ||
| 55 | // is no longer useful, and generates ~50 more bytes of code on i386... | ||
| 53 | uint32_t ivec; | 56 | uint32_t ivec; |
| 54 | size_t clen; | 57 | size_t clen; |
| 55 | int k; | 58 | int k; |
| @@ -64,13 +67,15 @@ PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, | |||
| 64 | //does libbb need a non-vararg version with just one (buf,len)? | 67 | //does libbb need a non-vararg version with just one (buf,len)? |
| 65 | 68 | ||
| 66 | if (c > 1) { | 69 | if (c > 1) { |
| 70 | //in yescrypt, c is always 1, so this if() branch is optimized out | ||
| 71 | uint64_t j; | ||
| 67 | /* T_i = U_1 ... */ | 72 | /* T_i = U_1 ... */ |
| 68 | memcpy(U, T, 32); | 73 | memcpy(U, T, 32); |
| 69 | for (j = 2; j <= c; j++) { | 74 | for (j = 2; j <= c; j++) { |
| 70 | /* Compute U_j. */ | 75 | /* Compute U_j. */ |
| 71 | hmac_peek_hash(&Phctx, (void*)U, U, 32, NULL); | 76 | hmac_peek_hash(&Phctx, (void*)U, U, 32, NULL); |
| 72 | /* ... xor U_j ... */ | 77 | /* ... xor U_j ... */ |
| 73 | for (k = 0; k < 32 / 8; k++) | 78 | for (k = 0; k < 32 / sizeof(long); k++) |
| 74 | T[k] ^= U[k]; | 79 | T[k] ^= U[k]; |
| 75 | //TODO: xorbuf32_aligned_long(T, U); | 80 | //TODO: xorbuf32_aligned_long(T, U); |
| 76 | } | 81 | } |
