* Rename librz/util/ubase64.c into librz/util/base64.c for consistency #5216 * Add Doxygen documentation to function in librz/util/base85.c #5216 * Add unit-tests for librz/util/base85.c #5216 * Refactor base85 API and internal functions #5216 base85 was using a FILE as an input and it used to print its result to STDOUT, which was very bad for having unit-testing or to use it to extend rz-hash functionality, since the solution I really had was through using pipes which isn't ideal as much as the refactoring one. * Extend rz-hash with base85 #5126 * Fix formatting #5216 * Extract base36 decoding function from subprojects/rzwinkd/iob_net.c to librz/util/base36.c #5216 - Also, added Doxygen docs to rz_base36_decode function * Added rz_base36_encode_dyn #5216 - this function encode a u64 value to it's char[13+1] base36 counterpart - later, it will be helpful in expanding the funcitionality of rz-hash - added its Doxygen docs * Expand rz-hash with base36 encoding/decoding #5216 * Refactor rz_base36_decode to return a suitable error code like -1 #5216 - that should help testing it later for valid and invalid decodings - keeping the original behaviour as it was in subprojects/rzwinkd/iob_net.c * Add unit-tests for base36 encoding & decoding functions #5216 * Fix formatting #5216 * Fix base36.h header file guards #5216 * Add base32 encoding & decoding #5216 added their Doxygen Docs as well * Add base32 encoding and decoding unti-tests #5216 * Expand rz-hash with base32 encoding/decoding functionality #5216 * Fix formatting #5216 * Fix add base32 to codec_name_bytes #5216 * Fix base32 docs #5216 * Add base16 encoding/decoding functions #5216 - added their Doxygen docs as well. * Add base16 unit-tests #5216 * Fix test_base85 conversions warnings #5216 * Expand rz-hash with base16 encoding/decoding functionality #5216 * Fix formatting #5216 * Fix doxygen docs #5216 * Restore subprojects/rizin-shell-parser/parser.c to match origin/dev * Fix the order by baseXX * Fix base16 - invert the logic in calculate_src_length * Fix base16 - intialize variables in rz_base16_encode * Fix base16 - null terminate the output buffer of rz_base16_encode_dyn * Fix base16 - get rid of unnecessary else in rz_base16_decode * Fix base16 - use `len & 1` instead of `(len % 2) != 0` * Fix base32 - invert the logic in calculate_src_length * Fix base32 - compress two return statments by using `rz_return_val_if_fail(src && dest, 0);` * Fix base32 - null terminate the output of rz_base32_encode * Fix base32 - get rid of unnecessary else in rz_base32_decode add more parentheses to split addition from mult for better clarity * Fix base32 - intialize variables in rz_base32_encode_dyn * Fix base36 - intialize `tmp` variable in rz_base36_encode_dyn * Fix base36 - use RZ_LOG_ERROR instead of eprintf * Fix base36 - use RZ_NULLABLE for the API interface * Fix base85 - use RZ_OUT & RZ_NULLABLE for the API interface * Fix base85 - use RZ_LOG_ERROR instead of eprintf * Fix base85 - use size_t instead of int for decode_tuple_buf * Fix base85 - remove unused varaible, `out_len`, in rz_base85_encode_dyn * Fix base85 - correct decode buffer size calculation The previous rz_base85_dec_buflen() underestimated the worst‑case output size (3 bytes per 4 input chars), causing overflows when using ‘z’/’y’ abbreviations. Update it to allocate 4 bytes per input character plus one for the NUL terminator, eliminating heap-buffer-overflow errors. * Fix formatting * Fix base85-test - use `newlines` variable to make sure line breaks were inserted as expected * Fix base85-test - remove unnecessary includes * Fix rz-hash test - updated rz-hash -L expected result * Fix crypto_base36 - use RZ_LOG_ERROR instead of eprintf * Fix base16 - compress rz_return_val_if_fail statements and move before locals * Update base16 - use hex.c existing encoding/decoding logic - base16.c encoding/decoding functions are now wrappers for hex.c `rz_hex_bin2str` and `rz_hex_str2bin` functions - updated related base16 unit testing and documentation - updated the integraion with rz-hash binary (or crypto_base16) * Fix formatting * Add documentation to rz_hex_bin2str * Fix base85 - add missing `reutrn` docs to rz_base85_encode function * Fix base85 - use RZ_NONNULL for dest and src function instead of RZ_NULLABLE * Fix base36 - use RZ_NONNULL for dest and src function instead of RZ_NULLABLE * Fix base16 - use RZ_NONNULL for dest and src function instead of RZ_NULLABLE * Fix base32 - use RZ_NONNULL for dest and src function instead of RZ_NULLABLE * Fix base16 - add missig checks for invalid inputs in rz_base16_encode & rz_base16_encode_dyn * Fix base32 - add missing checks for bad encoding * Fix - add missing SPDX * Fix Formatting * Add rz_base36_encode & rz_base36_decode_dyn functions to base36 API
119 lines
3.5 KiB
C
119 lines
3.5 KiB
C
// SPDX-FileCopyrightText: 2025 Ahmed Ibrahim <a.ibrahim8686@gmail.com>
|
||
// SPDX-License-Identifier: LGPL-3.0-only
|
||
|
||
#include <rz_util.h>
|
||
#include "minunit.h"
|
||
|
||
bool test_rz_base85_encode_dyn_nodelims(void) {
|
||
const char *src = "hello, ascii85";
|
||
char *dest = rz_base85_encode_dyn(src, strlen(src), 0, 0, 1);
|
||
mu_assert_streq(dest, "BOu!rD_*#>F(8ou3&L", "ascii85 encode mismatch");
|
||
free(dest);
|
||
mu_end;
|
||
}
|
||
|
||
bool test_rz_base85_encode_dyn_delims(void) {
|
||
const char *src = "hello, ascii85";
|
||
char *dest = rz_base85_encode_dyn(src, strlen(src), 1, 0, 1);
|
||
mu_assert_streq(dest, "<~BOu!rD_*#>F(8ou3&L~>", "ascii85 encode mismatch");
|
||
free(dest);
|
||
mu_end;
|
||
}
|
||
|
||
bool test_rz_base85_decode_dyn_nodelims(void) {
|
||
const char *src = "BOu!rD_*#>F(8ou3&L";
|
||
char *dest = rz_base85_decode_dyn(src, strlen(src), 0, 0, NULL);
|
||
mu_assert_streq(dest, "hello, ascii85", "decoder output mismatch");
|
||
free(dest);
|
||
mu_end;
|
||
}
|
||
|
||
bool test_rz_base85_decode_dyn_delims(void) {
|
||
const char *src = "<~BOu!rD_*#>F(8ou3&L~>";
|
||
char *dest = rz_base85_decode_dyn(src, strlen(src), 1, 0, NULL);
|
||
mu_assert_streq(dest, "hello, ascii85", "ascii85 decode with delimiters mismatch");
|
||
free(dest);
|
||
mu_end;
|
||
}
|
||
|
||
bool test_rz_base85_encode_decode_wrap10(void) {
|
||
char src[51];
|
||
memset(src, 'A', 50);
|
||
src[50] = '\0';
|
||
|
||
char *encoded = rz_base85_encode_dyn(src, strlen(src), 0, 10, 0);
|
||
|
||
int col = 0, newlines = 0;
|
||
for (size_t i = 0; encoded[i]; i++) {
|
||
if (encoded[i] == '\n') {
|
||
mu_assert_eq(col, 10, "line length before \\n not 10");
|
||
col = 0;
|
||
newlines++;
|
||
} else {
|
||
col++;
|
||
}
|
||
}
|
||
mu_assert_true(col <= 10, "final line exceeds wrap length");
|
||
mu_assert_true(newlines > 0, "no line breaks were inserted");
|
||
|
||
size_t decoded_len;
|
||
char *decoded = rz_base85_decode_dyn(encoded, strlen(encoded), 0, 0, &decoded_len);
|
||
|
||
mu_assert_eq(decoded_len, 50U, "decoded length mismatch");
|
||
mu_assert_true(memcmp(decoded, src, 50) == 0, "decoded data mismatch");
|
||
|
||
free(encoded);
|
||
free(decoded);
|
||
mu_end;
|
||
}
|
||
|
||
bool test_rz_base85_encode_decode_z_abbrev(void) {
|
||
const ut8 zeros[4] = { 0, 0, 0, 0 };
|
||
|
||
char *enc = rz_base85_encode_dyn((const char *)zeros, 4, 0, 0, 0);
|
||
mu_assert_notnull(enc, "rz_base85_encode_dyn returned NULL");
|
||
mu_assert_streq(enc, "z", "encode zeros should be 'z'");
|
||
|
||
size_t decoded_len;
|
||
char *decoded = rz_base85_decode_dyn("zz", -1, 0, 0, &decoded_len);
|
||
mu_assert_notnull(decoded, "rz_base85_decode_dyn returned NULL");
|
||
mu_assert_eq(decoded_len, 8U, "decoded length != 8");
|
||
|
||
for (size_t i = 0; i < decoded_len; i++) {
|
||
mu_assert_eq(decoded[i], '\0', "decoded byte non‑zero");
|
||
}
|
||
|
||
free(enc);
|
||
free(decoded);
|
||
mu_end;
|
||
}
|
||
|
||
bool test_rz_base85_decode_invalid_strict_vs_lenient(void) {
|
||
const char bad[] = "FCfN8v";
|
||
size_t decoded_len;
|
||
|
||
char *strict_out = rz_base85_decode_dyn(bad, -1, 0, 0, &decoded_len);
|
||
mu_assert_true(strict_out == NULL, "decoder accepted garbage in strict mode");
|
||
|
||
char *lenient_out = rz_base85_decode_dyn(bad, -1, 0, 1, &decoded_len);
|
||
mu_assert_notnull(lenient_out, "lenient decode returned NULL");
|
||
mu_assert_eq(decoded_len, 4U, "decoded length != 4");
|
||
mu_assert_true(memcmp(lenient_out, "test", 4) == 0, "lenient decode produced wrong bytes");
|
||
|
||
free(lenient_out);
|
||
mu_end;
|
||
}
|
||
|
||
int all_tests(void) {
|
||
mu_run_test(test_rz_base85_encode_dyn_nodelims);
|
||
mu_run_test(test_rz_base85_decode_dyn_nodelims);
|
||
mu_run_test(test_rz_base85_encode_dyn_delims);
|
||
mu_run_test(test_rz_base85_decode_dyn_delims);
|
||
mu_run_test(test_rz_base85_encode_decode_wrap10);
|
||
mu_run_test(test_rz_base85_encode_decode_z_abbrev);
|
||
mu_run_test(test_rz_base85_decode_invalid_strict_vs_lenient);
|
||
|
||
return tests_passed != tests_run;
|
||
}
|
||
|
||
mu_main(all_tests)
|