]> granicus.if.org Git - strace/commitdiff
util: add support for QUOTE_0_TERMINATED in user_style to ptrintstr_ex
authorEugene Syromyatnikov <evgsyr@gmail.com>
Mon, 10 Oct 2016 16:55:54 +0000 (19:55 +0300)
committerEugene Syromyatnikov <evgsyr@gmail.com>
Thu, 10 Nov 2016 19:44:18 +0000 (22:44 +0300)
This enables printing size-limited (expectedly) ASCIZ strings.

This is done by increasing umoven size limit for sized strings by one
byte above max_strlen (enabling copying possible NUL byte in case len is
greater than max_strlen) and decreasing size after copying by one byte
in case QUOTE_0_TERMINATED is set (due to user_style or usage of len of
-1).  As a result, there is one excess byte for string_quote in case
QUOTE_0_TERMINATED is set so string_quote can check for NUL termination
of strings up to size bytes in size (which is len or max_strlen, whatever
is greater).

The catch here is that when string is not properly NUL-terminated and
QUOTE_0_TERMINATED is provided in user_style and len is less than
max_strlen then last non-NUL byte is not printed.  But ellipsis is
printed instead, being indication that string is not terminated
properly.  QUOTE_OMIT_TRAILING_0 should be used instead in case this
behaviour is not intended.

* util.c (printstr_ex): Copy one excess byte in case of non-negative len
provided and it is more than max_strlen; handle case of max_strlen of 0
in case QUOTE_0_TERMINATED is set separately; check for need of printing
ellipsis by checking resulting style against QUOTE_0_TERMINATED.

util.c

diff --git a/util.c b/util.c
index 05c0e15cb1285bf49b00ac23a6fc8c11c1eb7bdd..f895f22720986ec9c8d6ea0884ea62744d6b53c5 100644 (file)
--- a/util.c
+++ b/util.c
@@ -838,13 +838,13 @@ printstr_ex(struct tcb *tcp, long addr, long len, unsigned int user_style)
                outstr = xmalloc(outstr_size);
        }
 
-       size = max_strlen;
+       size = max_strlen + 1;
        if (len == -1) {
                /*
                 * Treat as a NUL-terminated string: fetch one byte more
                 * because string_quote may look one byte ahead.
                 */
-               if (umovestr(tcp, addr, size + 1, str) < 0) {
+               if (umovestr(tcp, addr, size, str) < 0) {
                        printaddr(addr);
                        return;
                }
@@ -862,11 +862,23 @@ printstr_ex(struct tcb *tcp, long addr, long len, unsigned int user_style)
 
        style |= user_style;
 
+       if (style & QUOTE_0_TERMINATED) {
+               if (size) {
+                       --size;
+               } else {
+                       tprints((len == -1) || (len == 0) ? "\"\"" : "\"\"...");
+                       return;
+               }
+       }
+       if (size > max_strlen)
+               size = max_strlen;
+
        /* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
         * or we were requested to print more than -s NUM chars)...
         */
        ellipsis = (string_quote(str, outstr, size, style) &&
-                       (len < 0 || (unsigned long) len > max_strlen));
+                       ((style & QUOTE_0_TERMINATED) ||
+                               (unsigned long) len > max_strlen));
 
        tprints(outstr);
        if (ellipsis)