Skip to content

Commit cabd186

Browse files
committed
base64: add known-length calls for base64_to_bytes/get_maximum_length
1 parent 69de94f commit cabd186

File tree

11 files changed

+87
-12
lines changed

11 files changed

+87
-12
lines changed

include/wally.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,18 @@ inline int base64_get_maximum_length(const STR_IN& str_in, uint32_t flags, size_
463463
return detail::check_ret(__FUNCTION__, ret);
464464
}
465465

466+
template <class STR_IN>
467+
inline int base64_n_get_maximum_length(const STR_IN& str_in, size_t str_len, uint32_t flags, size_t* written) {
468+
int ret = ::wally_base64_n_get_maximum_length(detail::get_p(str_in), str_len, flags, written);
469+
return detail::check_ret(__FUNCTION__, ret);
470+
}
471+
472+
template <class STR_IN, class BYTES_OUT>
473+
inline int base64_n_to_bytes(const STR_IN& str_in, size_t str_len, uint32_t flags, BYTES_OUT& bytes_out, size_t* written) {
474+
int ret = ::wally_base64_n_to_bytes(detail::get_p(str_in), str_len, flags, bytes_out.data(), bytes_out.size(), written);
475+
return detail::check_ret(__FUNCTION__, ret);
476+
}
477+
466478
template <class STR_IN, class BYTES_OUT>
467479
inline int base64_to_bytes(const STR_IN& str_in, uint32_t flags, BYTES_OUT& bytes_out, size_t* written) {
468480
int ret = ::wally_base64_to_bytes(detail::get_p(str_in), flags, bytes_out.data(), bytes_out.size(), written);

include/wally_core.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,19 @@ WALLY_CORE_API int wally_base64_to_bytes(
350350
size_t len,
351351
size_t *written);
352352

353+
/**
354+
* Decode a known-length base64 encoded string back into into binary data.
355+
*
356+
* See `wally_base64_to_bytes`.
357+
*/
358+
WALLY_CORE_API int wally_base64_n_to_bytes(
359+
const char *str_in,
360+
size_t str_len,
361+
uint32_t flags,
362+
unsigned char *bytes_out,
363+
size_t len,
364+
size_t *written);
365+
353366
/**
354367
* Return the maximum length of a base64 encoded string once decoded into bytes.
355368
*
@@ -369,6 +382,17 @@ WALLY_CORE_API int wally_base64_get_maximum_length(
369382
uint32_t flags,
370383
size_t *written);
371384

385+
/**
386+
* Return the maximum length of a known-length base64 encoded string once decoded into bytes.
387+
*
388+
* See `wally_base64_get_maximum_length`.
389+
*/
390+
WALLY_CORE_API int wally_base64_n_get_maximum_length(
391+
const char *str_in,
392+
size_t str_len,
393+
uint32_t flags,
394+
size_t *written);
395+
372396

373397
#ifndef SWIG
374398
/** The type of an overridable function to allocate memory */

include/wally_map.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ WALLY_CORE_API int wally_map_combine(
333333
/**
334334
* Replace a maps contents with another map.
335335
*
336-
* :param map_in: the destination to combine into.
336+
* :param map_in: the destination to assign to.
337337
* :param source: the source to copy items from.
338338
*
339339
* .. note:: If this call fails, ``map_in`` is left untouched.

src/base_64.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,42 +25,55 @@ int wally_base64_from_bytes(const unsigned char *bytes, size_t bytes_len,
2525
return WALLY_OK;
2626
}
2727

28-
int wally_base64_get_maximum_length(const char *str_in, uint32_t flags, size_t *written)
28+
int wally_base64_n_get_maximum_length(const char *str_in, size_t str_len, uint32_t flags, size_t *written)
2929
{
3030
if (written)
3131
*written = 0;
3232

33-
if (!str_in || !*str_in || flags || !written)
33+
if (!str_in || !str_len || flags || !written)
3434
return WALLY_EINVAL;
3535

36-
*written = base64_decoded_length(strlen(str_in));
36+
*written = base64_decoded_length(str_len);
3737
return WALLY_OK;
3838
}
3939

40-
int wally_base64_to_bytes(const char *str_in, uint32_t flags,
41-
unsigned char *bytes_out, size_t len,
42-
size_t *written)
40+
int wally_base64_get_maximum_length(const char *str_in, uint32_t flags, size_t *written)
41+
{
42+
size_t str_len = str_in ? strlen(str_in) : 0;
43+
return wally_base64_n_get_maximum_length(str_in, str_len, flags, written);
44+
}
45+
46+
int wally_base64_n_to_bytes(const char *str_in, size_t str_len, uint32_t flags,
47+
unsigned char *bytes_out, size_t len,
48+
size_t *written)
4349
{
44-
size_t decode_len, str_in_len;
50+
size_t decode_len;
4551
ssize_t actual_len;
4652

4753
if (written)
4854
*written = 0;
4955

50-
if (!str_in || flags || !bytes_out || !len || !written)
56+
if (!str_in || !str_len || flags || !bytes_out || !len || !written)
5157
return WALLY_EINVAL;
5258

53-
str_in_len = strlen(str_in);
54-
decode_len = base64_decoded_length(str_in_len);
59+
decode_len = base64_decoded_length(str_len);
5560
if (len < decode_len) {
5661
/* Not enough space; return the amount required */
5762
*written = decode_len;
5863
return WALLY_OK;
5964
}
6065

61-
actual_len = base64_decode((char *)bytes_out, decode_len, str_in, str_in_len);
66+
actual_len = base64_decode((char *)bytes_out, decode_len, str_in, str_len);
6267
if (actual_len < 0)
6368
return WALLY_EINVAL; /* Invalid base64 data */
6469
*written = actual_len;
6570
return WALLY_OK;
6671
}
72+
73+
int wally_base64_to_bytes(const char *str_in, uint32_t flags,
74+
unsigned char *bytes_out, size_t len,
75+
size_t *written)
76+
{
77+
size_t str_len = str_in ? strlen(str_in) : 0;
78+
return wally_base64_n_to_bytes(str_in, str_len, flags, bytes_out, len, written);
79+
}

src/swig_java/swig.i

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,9 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
551551
%returns_size_t(wally_base58_n_to_bytes);
552552
%returns_string(wally_base64_from_bytes);
553553
%returns_size_t(wally_base64_to_bytes);
554+
%returns_size_t(wally_base64_n_to_bytes);
554555
%returns_size_t(wally_base64_get_maximum_length);
556+
%returns_size_t(wally_base64_n_get_maximum_length);
555557
%returns_string(wally_bip32_key_to_address);
556558
%returns_string(wally_bip32_key_to_addr_segwit);
557559
%returns_array_(wally_bip340_tagged_hash, 4, 5, SHA256_LEN);

src/swig_python/python_extra.py_in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ aes_cbc = _wrap_bin(aes_cbc, aes_cbc_get_maximum_length, resize=True)
119119
aes_cbc_with_ecdh_key = _wrap_bin(aes_cbc_with_ecdh_key, aes_cbc_with_ecdh_key_get_maximum_length, resize=True)
120120
base58_n_to_bytes = _wrap_bin(base58_n_to_bytes, base58_n_to_bytes_len, resize=True)
121121
base58_to_bytes = _wrap_bin(base58_to_bytes, base58_to_bytes_len, resize=True)
122+
base64_n_to_bytes = _wrap_bin(base64_n_to_bytes, base64_n_get_maximum_length, resize=True)
122123
base64_to_bytes = _wrap_bin(base64_to_bytes, base64_get_maximum_length, resize=True)
123124
bip32_key_from_base58 = bip32_key_from_base58_alloc
124125
bip32_key_from_base58_n = bip32_key_from_base58_n_alloc

src/test/test_base64.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,19 @@ def test_vectors(self):
3535
self.assertEqual(ret, WALLY_OK)
3636
self.assertTrue(max_len >= len(str_in))
3737

38+
ret, max_len_n = wally_base64_n_get_maximum_length(b64_in, len(b64_in), 0)
39+
self.assertEqual(ret, WALLY_OK)
40+
self.assertEqual(max_len, max_len_n)
41+
3842
ret, b64_out = wally_base64_from_bytes(utf8(str_in), len(str_in), 0)
3943
self.assertEqual((ret, b64_out), (WALLY_OK, b64_in))
4044

4145
ret, written = wally_base64_to_bytes(utf8(b64_in), 0, buf, max_len)
4246
self.assertEqual((ret, buf[:written]), (WALLY_OK, utf8(str_in)))
4347

48+
ret, written = wally_base64_n_to_bytes(utf8(b64_in), len(b64_in), 0, buf, max_len)
49+
self.assertEqual((ret, buf[:written]), (WALLY_OK, utf8(str_in)))
50+
4451
def test_get_maximum_length(self):
4552
# Invalid args
4653
valid_b64 = utf8(ROUND_TRIP_CASES[0][1])
@@ -69,6 +76,7 @@ def test_base64_to_bytes(self):
6976
# Invalid args
7077
buf, buf_len = make_cbuffer('00' * 1024)
7178
valid_b64 = utf8(ROUND_TRIP_CASES[0][1])
79+
valid_len = len(valid_b64)
7280
_, max_len = wally_base64_get_maximum_length(valid_b64, 0)
7381

7482
for args in [
@@ -80,6 +88,13 @@ def test_base64_to_bytes(self):
8088
ret, written = wally_base64_to_bytes(*args)
8189
self.assertEqual((ret, written), (WALLY_EINVAL, 0))
8290

91+
for args in [
92+
(None, valid_len, 0, buf, max_len), # NULL base64 string, non-0 length
93+
(valid_b64, 0, 0, buf, max_len), # Non-NULL base64 string, 0 length
94+
]:
95+
ret, written = wally_base64_n_to_bytes(*args)
96+
self.assertEqual((ret, written), (WALLY_EINVAL, 0))
97+
8398
# Too short output length returns the number of bytes needed
8499
ret, written = wally_base64_to_bytes(valid_b64, 0, buf, max_len-1)
85100
self.assertEqual((ret, written), (WALLY_OK, max_len))

src/test/util.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ class wally_psbt(Structure):
300300
('wally_base58_to_bytes', c_int, [c_char_p, c_uint32, c_void_p, c_size_t, c_size_t_p]),
301301
('wally_base64_from_bytes', c_int, [c_void_p, c_size_t, c_uint32, c_char_p_p]),
302302
('wally_base64_get_maximum_length', c_int, [c_char_p, c_uint32, c_size_t_p]),
303+
('wally_base64_n_get_maximum_length', c_int, [c_char_p, c_size_t, c_uint32, c_size_t_p]),
304+
('wally_base64_n_to_bytes', c_int, [c_char_p, c_size_t, c_uint32, c_void_p, c_size_t, c_size_t_p]),
303305
('wally_base64_to_bytes', c_int, [c_char_p, c_uint32, c_void_p, c_size_t, c_size_t_p]),
304306
('wally_bip32_key_to_addr_segwit', c_int, [POINTER(ext_key), c_char_p, c_uint32, c_char_p_p]),
305307
('wally_bip32_key_to_address', c_int, [POINTER(ext_key), c_uint32, c_uint32, c_char_p_p]),

src/wasm_package/src/functions.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/wasm_package/src/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export function base58_get_length(str_in: string): number;
5656
export function base58_n_get_length(str_in: string, str_len: number): number;
5757
export function base64_from_bytes(bytes: Buffer|Uint8Array, flags: number): string;
5858
export function base64_get_maximum_length(str_in: string, flags: number): number;
59+
export function base64_n_get_maximum_length(str_in: string, str_len: number, flags: number): number;
5960
export function bip32_key_free(hdkey: Ref_ext_key): void;
6061
export function bip32_key_from_base58(base58: string): Ref_ext_key;
6162
export function bip32_key_from_base58_n(base58: string, base58_len: number): Ref_ext_key;
@@ -741,6 +742,7 @@ export function asset_pak_whitelistproof(online_keys: Buffer|Uint8Array, offline
741742
export function asset_surjectionproof(output_asset: Buffer|Uint8Array, output_abf: Buffer|Uint8Array, output_generator: Buffer|Uint8Array, bytes: Buffer|Uint8Array, asset: Buffer|Uint8Array, abf: Buffer|Uint8Array, generator: Buffer|Uint8Array): Buffer;
742743
export function base58_n_to_bytes(str_in: string, str_len: number, flags: number): Buffer;
743744
export function base58_to_bytes(str_in: string, flags: number): Buffer;
745+
export function base64_n_to_bytes(str_in: string, str_len: number, flags: number): Buffer;
744746
export function base64_to_bytes(str_in: string, flags: number): Buffer;
745747
export function descriptor_get_key_child_path_str(descriptor: Ref_wally_descriptor, index: number): string;
746748
export function descriptor_get_key_origin_path_str(descriptor: Ref_wally_descriptor, index: number): string;

0 commit comments

Comments
 (0)