[09/11] stdio-common: Allow skipping initial bytes in __printf_buffer for %n
Checks
Context |
Check |
Description |
redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-arm |
success
|
Testing passed
|
Commit Message
Making the written field signed allows subtraction of a prefix count
in case multiple writes happen to the same buffer.
---
include/printf_buffer.h | 8 +++++---
stdio-common/tst-printf_buffer.c | 18 ++++++++++++++++++
2 files changed, 23 insertions(+), 3 deletions(-)
Comments
On 09/02/24 12:25, Florian Weimer wrote:
> Making the written field signed allows subtraction of a prefix count
> in case multiple writes happen to the same buffer.
LGTM, thanks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> include/printf_buffer.h | 8 +++++---
> stdio-common/tst-printf_buffer.c | 18 ++++++++++++++++++
> 2 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/include/printf_buffer.h b/include/printf_buffer.h
> index a5483e8a97..2400371b94 100644
> --- a/include/printf_buffer.h
> +++ b/include/printf_buffer.h
> @@ -92,8 +92,10 @@ struct __printf_buffer
> buffer). Potentially updated on flush. The actual number of
> written bytes also includes the unflushed-but-written buffer
> part, write_ptr - write_base. A 64-bit value is used to avoid
> - the need for overflow checks. */
> - uint64_t written;
> + the need for intermediate overflow checks. Negative values can
> + be used to ignore leading parts of the buffer for %n computations
> + (for repeated __printf_buffer calls to the same buffer). */
> + int64_t written;
>
> /* Identifies the flush callback. */
> enum __printf_buffer_mode mode;
> @@ -225,7 +227,7 @@ struct __wprintf_buffer
> wchar_t *write_base;
> wchar_t *write_ptr;
> wchar_t *write_end;
> - uint64_t written;
> + int64_t written;
> enum __wprintf_buffer_mode mode;
> };
>
> diff --git a/stdio-common/tst-printf_buffer.c b/stdio-common/tst-printf_buffer.c
> index d12da8c939..2a3ee511d0 100644
> --- a/stdio-common/tst-printf_buffer.c
> +++ b/stdio-common/tst-printf_buffer.c
> @@ -132,6 +132,24 @@ do_test (void)
> TEST_VERIFY (!__printf_buffer_has_failed (&buf.base));
> TEST_COMPARE (__printf_buffer_asprintf_free (&buf), -1);
> }
> +
> + /* Test %n with initial skip. */
> + {
> + struct __printf_buffer_asprintf buf;
> + __printf_buffer_asprintf_init (&buf);
> + __printf_buffer (&buf.base, "abc");
> + buf.base.written = -2;
> + int n = -1;
> + __printf_buffer (&buf.base, "D%nEF", &n);
> + TEST_COMPARE (n, 2); /* Two characters were skipped. */
> + TEST_VERIFY (buf.base.write_base == buf.direct);
> + TEST_COMPARE_BLOB (buf.base.write_base,
> + buf.base.write_ptr - buf.base.write_base, "abcDEF", 6);
> + TEST_VERIFY (!__printf_buffer_has_failed (&buf.base));
> + TEST_COMPARE (__printf_buffer_done (&buf.base), 4); /* Two skipped. */
> + TEST_COMPARE (__printf_buffer_asprintf_free (&buf), -1);
> + }
> +
> return 0;
> }
>
@@ -92,8 +92,10 @@ struct __printf_buffer
buffer). Potentially updated on flush. The actual number of
written bytes also includes the unflushed-but-written buffer
part, write_ptr - write_base. A 64-bit value is used to avoid
- the need for overflow checks. */
- uint64_t written;
+ the need for intermediate overflow checks. Negative values can
+ be used to ignore leading parts of the buffer for %n computations
+ (for repeated __printf_buffer calls to the same buffer). */
+ int64_t written;
/* Identifies the flush callback. */
enum __printf_buffer_mode mode;
@@ -225,7 +227,7 @@ struct __wprintf_buffer
wchar_t *write_base;
wchar_t *write_ptr;
wchar_t *write_end;
- uint64_t written;
+ int64_t written;
enum __wprintf_buffer_mode mode;
};
@@ -132,6 +132,24 @@ do_test (void)
TEST_VERIFY (!__printf_buffer_has_failed (&buf.base));
TEST_COMPARE (__printf_buffer_asprintf_free (&buf), -1);
}
+
+ /* Test %n with initial skip. */
+ {
+ struct __printf_buffer_asprintf buf;
+ __printf_buffer_asprintf_init (&buf);
+ __printf_buffer (&buf.base, "abc");
+ buf.base.written = -2;
+ int n = -1;
+ __printf_buffer (&buf.base, "D%nEF", &n);
+ TEST_COMPARE (n, 2); /* Two characters were skipped. */
+ TEST_VERIFY (buf.base.write_base == buf.direct);
+ TEST_COMPARE_BLOB (buf.base.write_base,
+ buf.base.write_ptr - buf.base.write_base, "abcDEF", 6);
+ TEST_VERIFY (!__printf_buffer_has_failed (&buf.base));
+ TEST_COMPARE (__printf_buffer_done (&buf.base), 4); /* Two skipped. */
+ TEST_COMPARE (__printf_buffer_asprintf_free (&buf), -1);
+ }
+
return 0;
}