Skip to content

Commit 5020b14

Browse files
jeepeedpgeorge
authored andcommitted
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.
1 parent dde0735 commit 5020b14

File tree

5 files changed

+12
-11
lines changed

5 files changed

+12
-11
lines changed

ports/unix/coverage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ STATIC mp_obj_t extra_coverage(void) {
186186
mp_printf(&mp_plat_print, "%ld\n", 123); // long
187187
mp_printf(&mp_plat_print, "%lx\n", 0x123); // long hex
188188
mp_printf(&mp_plat_print, "%X\n", 0x1abcdef); // capital hex
189-
mp_printf(&mp_plat_print, "%.2s %.3s\n", "abc", "abc"); // fixed string precision
189+
mp_printf(&mp_plat_print, "%.2s %.3s '%4.4s' '%5.5q' '%.3q'\n", "abc", "abc", "abc", MP_QSTR_True, MP_QSTR_True); // fixed string precision
190190
mp_printf(&mp_plat_print, "%.*s\n", -1, "abc"); // negative string precision
191191
mp_printf(&mp_plat_print, "%b %b\n", 0, 1); // bools
192192
#ifndef NDEBUG

py/mpprint.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,10 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
484484
qstr qst = va_arg(args, qstr);
485485
size_t len;
486486
const char *str = (const char *)qstr_data(qst, &len);
487-
if (prec < 0) {
488-
prec = len;
487+
if (prec >= 0 && (size_t)prec < len) {
488+
len = prec;
489489
}
490-
chrs += mp_print_strn(print, str, prec, flags, fill, width);
490+
chrs += mp_print_strn(print, str, len, flags, fill, width);
491491
break;
492492
}
493493
case 's': {
@@ -499,10 +499,11 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
499499
break;
500500
}
501501
#endif
502-
if (prec < 0) {
503-
prec = strlen(str);
502+
size_t len = strlen(str);
503+
if (prec >= 0 && (size_t)prec < len) {
504+
len = prec;
504505
}
505-
chrs += mp_print_strn(print, str, prec, flags, fill, width);
506+
chrs += mp_print_strn(print, str, len, flags, fill, width);
506507
break;
507508
}
508509
case 'd': {

py/objstr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ STATIC void str_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
123123
bool is_bytes = true;
124124
#endif
125125
if (kind == PRINT_RAW || (!MICROPY_PY_BUILTINS_STR_UNICODE && kind == PRINT_STR && !is_bytes)) {
126-
mp_printf(print, "%.*s", str_len, str_data);
126+
print->print_strn(print->data, (const char *)str_data, str_len);
127127
} else {
128128
if (is_bytes) {
129-
mp_print_str(print, "b");
129+
print->print_strn(print->data, "b", 1);
130130
}
131131
mp_str_print_quoted(print, str_data, str_len, is_bytes);
132132
}

py/objstrunicode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ STATIC void uni_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
9292
}
9393
#endif
9494
if (kind == PRINT_STR) {
95-
mp_printf(print, "%.*s", str_len, str_data);
95+
print->print_strn(print->data, (const char *)str_data, str_len);
9696
} else {
9797
uni_print_quoted(print, str_data, str_len);
9898
}

tests/unix/extra_coverage.py.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
123
55
123
66
1ABCDEF
7-
ab abc
7+
ab abc ' abc' ' True' 'Tru'
88

99
false true
1010
(null)

0 commit comments

Comments
 (0)