summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorJoris Peeraer <jorispeeraer@gmail.com>2020-10-22 10:38:03 +0200
committerDamien George <damien@micropython.org>2020-12-07 23:32:06 +1100
commit5020b14d5419065f1a5ef5aed1be7badee28c9bf (patch)
tree3a5ecda9ef9027206a3dbb4c3df5fab99803a32d /py
parentdde0735ac1629aca4f7d41334f25b75dd8d35010 (diff)
py/mpprint: Fix length calculation for strings with precision-modifier.
Two issues are tackled: 1. The calculation of the correct length to print is fixed to treat the precision as a maximum length instead as the exact length. This is done for both qstr (%q) and for regular str (%s). 2. Fix the incorrect use of mp_printf("%.*s") to mp_print_strn(). Because of the fix of above issue, some testcases that would print an embedded null-byte (^@ in test-output) would now fail. The bug here is that "%s" was used to print null-bytes. Instead, mp_print_strn is used to make sure all bytes are outputted and the exact length is respected. Test-cases are added for both %s and %q with a combination of precision and padding specifiers.
Diffstat (limited to 'py')
-rw-r--r--py/mpprint.c13
-rw-r--r--py/objstr.c4
-rw-r--r--py/objstrunicode.c2
3 files changed, 10 insertions, 9 deletions
diff --git a/py/mpprint.c b/py/mpprint.c
index 31cf73bb5..3218bd2f4 100644
--- a/py/mpprint.c
+++ b/py/mpprint.c
@@ -484,10 +484,10 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
qstr qst = va_arg(args, qstr);
size_t len;
const char *str = (const char *)qstr_data(qst, &len);
- if (prec < 0) {
- prec = len;
+ if (prec >= 0 && (size_t)prec < len) {
+ len = prec;
}
- chrs += mp_print_strn(print, str, prec, flags, fill, width);
+ chrs += mp_print_strn(print, str, len, flags, fill, width);
break;
}
case 's': {
@@ -499,10 +499,11 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
break;
}
#endif
- if (prec < 0) {
- prec = strlen(str);
+ size_t len = strlen(str);
+ if (prec >= 0 && (size_t)prec < len) {
+ len = prec;
}
- chrs += mp_print_strn(print, str, prec, flags, fill, width);
+ chrs += mp_print_strn(print, str, len, flags, fill, width);
break;
}
case 'd': {
diff --git a/py/objstr.c b/py/objstr.c
index 84728e6f2..9f8da873d 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -123,10 +123,10 @@ STATIC void str_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
bool is_bytes = true;
#endif
if (kind == PRINT_RAW || (!MICROPY_PY_BUILTINS_STR_UNICODE && kind == PRINT_STR && !is_bytes)) {
- mp_printf(print, "%.*s", str_len, str_data);
+ print->print_strn(print->data, (const char *)str_data, str_len);
} else {
if (is_bytes) {
- mp_print_str(print, "b");
+ print->print_strn(print->data, "b", 1);
}
mp_str_print_quoted(print, str_data, str_len, is_bytes);
}
diff --git a/py/objstrunicode.c b/py/objstrunicode.c
index b21df22a3..ed79ad68a 100644
--- a/py/objstrunicode.c
+++ b/py/objstrunicode.c
@@ -92,7 +92,7 @@ STATIC void uni_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
}
#endif
if (kind == PRINT_STR) {
- mp_printf(print, "%.*s", str_len, str_data);
+ print->print_strn(print->data, (const char *)str_data, str_len);
} else {
uni_print_quoted(print, str_data, str_len);
}