← Commit list

e0c8b4b451

Max Dymond
Max Dymond
2026-09-21
SUCCESS Duration: 417s

Subject

base64: avoid repeated input loads when encoding

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/curlx/base64.c+9 -4
@@ -207,10 +207,15 @@ static CURLcode base64_encode(const char *table64,
return CURLE_OUT_OF_MEMORY;
while(insize >= 3) {
- *output++ = table64[in[0] >> 2];
- *output++ = table64[((in[0] & 0x03) << 4) | (in[1] >> 4)];
- *output++ = table64[((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6)];
- *output++ = table64[in[2] & 0x3F];
+ /* Load all three input bytes before storing output, avoiding reloads when
+ the compiler cannot rule out aliasing. Extract four 6-bit indices from
+ the packed value; byte-wise loads avoid alignment and endian issues. */
+ uint32_t bits = ((uint32_t)in[0] << 16) |
+ ((uint32_t)in[1] << 8) | in[2];
+ *output++ = table64[bits >> 18];
+ *output++ = table64[(bits >> 12) & 0x3F];
+ *output++ = table64[(bits >> 6) & 0x3F];
+ *output++ = table64[bits & 0x3F];
insize -= 3;
in += 3;
}
tests/unit/unit1302.c+24 -0
@@ -162,6 +162,30 @@ static CURLcode test_unit1302(const char *arg)
curlx_safefree(decoded);
}
+ {
+ unsigned char binary[256];
+ size_t length;
+ for(i = 0; i < sizeof(binary); i++)
+ binary[i] = (unsigned char)i;
+ for(length = 1; length <= sizeof(binary); length++) {
+ char *encoded;
+ unsigned char *decoded;
+ size_t enclen;
+ size_t declen;
+ result = curlx_base64_encode(binary, length, &encoded, &enclen);
+ abort_unless(result == CURLE_OK, "binary encoding failed");
+ fail_unless(enclen == (length + 2) / 3 * 4, "wrong encoded size");
+ fail_unless(!encoded[enclen], "encoded data is not terminated");
+ result = curlx_base64_decode(encoded, &decoded, &declen);
+ curlx_free(encoded);
+ abort_unless(result == CURLE_OK, "binary decoding failed");
+ fail_unless(declen == length, "wrong decoded size");
+ fail_unless(!memcmp(decoded, binary, length), "wrong decoded data");
+ fail_unless(!decoded[declen], "decoded data is not terminated");
+ curlx_free(decoded);
+ }
+ }
+
for(i = 0; i < CURL_ARRAYSIZE(url); i++) {
const struct etest *e = &url[i];
char *out;