forked from pool/strace
195 lines
5.0 KiB
Diff
195 lines
5.0 KiB
Diff
2008-11-09 Dmitry V. Levin <ldv@altlinux.org>
|
|
|
|
* util.c (string_quote): Fix support for NUL-terminated string.
|
|
Add comments.
|
|
(printpathn): Fix the case when "..." was appended to the output
|
|
but no truncation was actually made. Add comments.
|
|
(printstr): Fix memory allocation. Fix two cases when "..." was
|
|
appended to the output but no truncation was actually made.
|
|
Add comments.
|
|
|
|
Index: util.c
|
|
===================================================================
|
|
RCS file: /cvsroot/strace/strace/util.c,v
|
|
retrieving revision 1.80
|
|
retrieving revision 1.81
|
|
diff -u -a -p -u -p -a -r1.80 -r1.81
|
|
--- util.c 10 Nov 2008 22:21:41 -0000 1.80
|
|
+++ util.c 10 Nov 2008 23:19:13 -0000 1.81
|
|
@@ -407,6 +407,12 @@ unsigned long uid;
|
|
|
|
static char path[MAXPATHLEN + 1];
|
|
|
|
+/*
|
|
+ * Quote string `instr' of length `size'
|
|
+ * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
|
|
+ * If `len' < 0, treat `instr' as a NUL-terminated string
|
|
+ * and quote at most (`size' - 1) bytes.
|
|
+ */
|
|
static int
|
|
string_quote(const char *instr, char *outstr, int len, int size)
|
|
{
|
|
@@ -417,12 +423,18 @@ string_quote(const char *instr, char *ou
|
|
if (xflag > 1)
|
|
usehex = 1;
|
|
else if (xflag) {
|
|
+ /* Check for presence of symbol which require
|
|
+ to hex-quote the whole string. */
|
|
for (i = 0; i < size; ++i) {
|
|
c = ustr[i];
|
|
- if (len < 0 && i == size - 2 && c != '\0')
|
|
- ++i;
|
|
- if (len < 0 && c == '\0')
|
|
- break;
|
|
+ /* Check for NUL-terminated string. */
|
|
+ if (len < 0) {
|
|
+ if (c == '\0')
|
|
+ break;
|
|
+ /* Quote at most size - 1 bytes. */
|
|
+ if (i == size - 1)
|
|
+ continue;
|
|
+ }
|
|
if (!isprint(c) && !isspace(c)) {
|
|
usehex = 1;
|
|
break;
|
|
@@ -433,20 +445,31 @@ string_quote(const char *instr, char *ou
|
|
*s++ = '\"';
|
|
|
|
if (usehex) {
|
|
+ /* Hex-quote the whole string. */
|
|
for (i = 0; i < size; ++i) {
|
|
c = ustr[i];
|
|
- if (len < 0 && c == '\0')
|
|
- break;
|
|
+ /* Check for NUL-terminated string. */
|
|
+ if (len < 0) {
|
|
+ if (c == '\0')
|
|
+ break;
|
|
+ /* Quote at most size - 1 bytes. */
|
|
+ if (i == size - 1)
|
|
+ continue;
|
|
+ }
|
|
sprintf(s, "\\x%02x", c);
|
|
s += 4;
|
|
}
|
|
} else {
|
|
for (i = 0; i < size; ++i) {
|
|
c = ustr[i];
|
|
- if (len < 0 && i == size - 2 && c != '\0')
|
|
- ++i;
|
|
- if (len < 0 && c == '\0')
|
|
- break;
|
|
+ /* Check for NUL-terminated string. */
|
|
+ if (len < 0) {
|
|
+ if (c == '\0')
|
|
+ break;
|
|
+ /* Quote at most size - 1 bytes. */
|
|
+ if (i == size - 1)
|
|
+ continue;
|
|
+ }
|
|
switch (c) {
|
|
case '\"': case '\\':
|
|
*s++ = '\\';
|
|
@@ -495,18 +518,25 @@ string_quote(const char *instr, char *ou
|
|
return i == size;
|
|
}
|
|
|
|
+/*
|
|
+ * Print path string specified by address `addr' and length `n'.
|
|
+ * If path length exceeds `n', append `...' to the output.
|
|
+ */
|
|
void
|
|
printpathn(struct tcb *tcp, long addr, int n)
|
|
{
|
|
- if (n > sizeof path - 1)
|
|
- n = sizeof path - 1;
|
|
-
|
|
- if (addr == 0) {
|
|
+ if (!addr) {
|
|
tprintf("NULL");
|
|
return;
|
|
}
|
|
|
|
+ /* Cap path length to the path buffer size,
|
|
+ and NUL-terminate the buffer. */
|
|
+ if (n > sizeof path - 1)
|
|
+ n = sizeof path - 1;
|
|
path[n] = '\0';
|
|
+
|
|
+ /* Fetch one byte more to find out whether path length > n. */
|
|
if (umovestr(tcp, addr, n + 1, path) < 0)
|
|
tprintf("%#lx", addr);
|
|
else {
|
|
@@ -515,7 +545,8 @@ printpathn(struct tcb *tcp, long addr, i
|
|
|
|
if (trunc)
|
|
path[n] = '\0';
|
|
- if (string_quote(path, outstr, -1, n + 1) || trunc)
|
|
+ (void) string_quote(path, outstr, -1, n + 1);
|
|
+ if (trunc)
|
|
strcat(outstr, "...");
|
|
tprintf("%s", outstr);
|
|
}
|
|
@@ -527,6 +558,11 @@ printpath(struct tcb *tcp, long addr)
|
|
printpathn(tcp, addr, sizeof path - 1);
|
|
}
|
|
|
|
+/*
|
|
+ * Print string specified by address `addr' and length `len'.
|
|
+ * If `len' < 0, treat the string as a NUL-terminated string.
|
|
+ * If string length exceeds `max_strlen', append `...' to the output.
|
|
+ */
|
|
void
|
|
printstr(struct tcb *tcp, long addr, int len)
|
|
{
|
|
@@ -538,32 +574,39 @@ printstr(struct tcb *tcp, long addr, int
|
|
tprintf("NULL");
|
|
return;
|
|
}
|
|
- if (!str) {
|
|
- if ((str = malloc(max_strlen + 1)) == NULL
|
|
- || (outstr = malloc(4*max_strlen
|
|
- + sizeof "\"\"...")) == NULL) {
|
|
- fprintf(stderr, "out of memory\n");
|
|
- tprintf("%#lx", addr);
|
|
- return;
|
|
- }
|
|
+ /* Allocate static buffers if they are not allocated yet. */
|
|
+ if (!str)
|
|
+ str = malloc(max_strlen + 1);
|
|
+ if (!outstr)
|
|
+ outstr = malloc(4 * max_strlen + sizeof "\"...\"");
|
|
+ if (!str || !outstr) {
|
|
+ fprintf(stderr, "out of memory\n");
|
|
+ tprintf("%#lx", addr);
|
|
+ return;
|
|
}
|
|
|
|
if (len < 0) {
|
|
+ /*
|
|
+ * Treat as a NUL-terminated string: fetch one byte more
|
|
+ * because string_quote() quotes one byte less.
|
|
+ */
|
|
size = max_strlen + 1;
|
|
+ str[max_strlen] = '\0';
|
|
if (umovestr(tcp, addr, size, str) < 0) {
|
|
tprintf("%#lx", addr);
|
|
return;
|
|
}
|
|
}
|
|
else {
|
|
- size = MIN(len, max_strlen + 1);
|
|
+ size = MIN(len, max_strlen);
|
|
if (umoven(tcp, addr, size, str) < 0) {
|
|
tprintf("%#lx", addr);
|
|
return;
|
|
}
|
|
}
|
|
|
|
- if (string_quote(str, outstr, len, size))
|
|
+ if (string_quote(str, outstr, len, size) &&
|
|
+ (len < 0 || len > max_strlen))
|
|
strcat(outstr, "...");
|
|
|
|
tprintf("%s", outstr);
|