diff options
author | Glenn Moloney <glenn.moloney@gmail.com> | 2024-08-13 08:38:20 +1000 |
---|---|---|
committer | Glenn Moloney <glenn.moloney@gmail.com> | 2024-08-19 14:18:34 +1000 |
commit | 6367099f8365c22b42474818ce5fdb9b35591ade (patch) | |
tree | 9784e255a91ef704201d149194753938598cffa3 /py/objstr.c | |
parent | e9814e987bcc816fb67e38748a5afce466c45606 (diff) | |
download | micropython-6367099f8365c22b42474818ce5fdb9b35591ade.tar.gz micropython-6367099f8365c22b42474818ce5fdb9b35591ade.zip |
py/objstr: Skip whitespace in bytes.fromhex().
Skip whitespace characters between pairs of hex numbers.
This makes `bytes.fromhex()` compatible with cpython.
Includes simple test in `tests/basic/builtin_str_hex.py`.
Signed-off-by: Glenn Moloney <glenn.moloney@gmail.com>
Diffstat (limited to 'py/objstr.c')
-rw-r--r-- | py/objstr.c | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/py/objstr.c b/py/objstr.c index 757da827c0..fc0623eb7a 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -2014,27 +2014,21 @@ mp_obj_t mp_obj_bytes_fromhex(mp_obj_t type_in, mp_obj_t data) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); - if ((bufinfo.len & 1) != 0) { - mp_raise_ValueError(MP_ERROR_TEXT("odd-length string")); - } vstr_t vstr; vstr_init_len(&vstr, bufinfo.len / 2); byte *in = bufinfo.buf, *out = (byte *)vstr.buf; - byte hex_byte = 0; - for (mp_uint_t i = bufinfo.len; i--;) { - byte hex_ch = *in++; - if (unichar_isxdigit(hex_ch)) { - hex_byte += unichar_xdigit_value(hex_ch); - } else { - mp_raise_ValueError(MP_ERROR_TEXT("non-hex digit found")); + byte *in_end = in + bufinfo.len; + mp_uint_t ch1, ch2; + while (in < in_end) { + if (unichar_isspace(ch1 = *in++)) { + continue; // Skip whitespace between hex digit pairs } - if (i & 1) { - hex_byte <<= 4; - } else { - *out++ = hex_byte; - hex_byte = 0; + if (in == in_end || !unichar_isxdigit(ch1) || !unichar_isxdigit(ch2 = *in++)) { + mp_raise_ValueError(MP_ERROR_TEXT("non-hex digit")); } + *out++ = (byte)((unichar_xdigit_value(ch1) << 4) | unichar_xdigit_value(ch2)); } + vstr.len = out - (byte *)vstr.buf; // Length may be shorter due to whitespace in input return mp_obj_new_str_type_from_vstr(MP_OBJ_TO_PTR(type_in), &vstr); } |