]>
Commit | Line | Data |
---|---|---|
86325e07 SP |
1 | --- util.c |
2 | +++ util.c | |
3 | @@ -407,6 +407,12 @@ unsigned long uid; | |
4 | ||
5 | static char path[MAXPATHLEN + 1]; | |
6 | ||
7 | +/* | |
8 | + * Quote string `instr' of length `size' | |
9 | + * Write up to (3 + `size' * 4) bytes to `outstr' buffer. | |
10 | + * If `len' < 0, treat `instr' as a NUL-terminated string | |
11 | + * and quote at most (`size' - 1) bytes. | |
12 | + */ | |
13 | static int | |
14 | string_quote(const char *instr, char *outstr, int len, int size) | |
15 | { | |
16 | @@ -417,12 +423,18 @@ string_quote(const char *instr, char *outstr, int len, int size) | |
17 | if (xflag > 1) | |
18 | usehex = 1; | |
19 | else if (xflag) { | |
20 | + /* Check for presence of symbol which require | |
21 | + to hex-quote the whole string. */ | |
22 | for (i = 0; i < size; ++i) { | |
23 | c = ustr[i]; | |
24 | - if (len < 0 && i == size - 2 && c != '\0') | |
25 | - ++i; | |
26 | - if (len < 0 && c == '\0') | |
27 | - break; | |
28 | + /* Check for NUL-terminated string. */ | |
29 | + if (len < 0) { | |
30 | + if (c == '\0') | |
31 | + break; | |
32 | + /* Quote at most size - 1 bytes. */ | |
33 | + if (i == size - 1) | |
34 | + continue; | |
35 | + } | |
36 | if (!isprint(c) && !isspace(c)) { | |
37 | usehex = 1; | |
38 | break; | |
39 | @@ -433,20 +445,31 @@ string_quote(const char *instr, char *outstr, int len, int size) | |
40 | *s++ = '\"'; | |
41 | ||
42 | if (usehex) { | |
43 | + /* Hex-quote the whole string. */ | |
44 | for (i = 0; i < size; ++i) { | |
45 | c = ustr[i]; | |
46 | - if (len < 0 && c == '\0') | |
47 | - break; | |
48 | + /* Check for NUL-terminated string. */ | |
49 | + if (len < 0) { | |
50 | + if (c == '\0') | |
51 | + break; | |
52 | + /* Quote at most size - 1 bytes. */ | |
53 | + if (i == size - 1) | |
54 | + continue; | |
55 | + } | |
56 | sprintf(s, "\\x%02x", c); | |
57 | s += 4; | |
58 | } | |
59 | } else { | |
60 | for (i = 0; i < size; ++i) { | |
61 | c = ustr[i]; | |
62 | - if (len < 0 && i == size - 2 && c != '\0') | |
63 | - ++i; | |
64 | - if (len < 0 && c == '\0') | |
65 | - break; | |
66 | + /* Check for NUL-terminated string. */ | |
67 | + if (len < 0) { | |
68 | + if (c == '\0') | |
69 | + break; | |
70 | + /* Quote at most size - 1 bytes. */ | |
71 | + if (i == size - 1) | |
72 | + continue; | |
73 | + } | |
74 | switch (c) { | |
75 | case '\"': case '\\': | |
76 | *s++ = '\\'; | |
77 | @@ -495,18 +518,25 @@ string_quote(const char *instr, char *outstr, int len, int size) | |
78 | return i == size; | |
79 | } | |
80 | ||
81 | +/* | |
82 | + * Print path string specified by address `addr' and length `n'. | |
83 | + * If path length exceeds `n', append `...' to the output. | |
84 | + */ | |
85 | void | |
86 | printpathn(struct tcb *tcp, long addr, int n) | |
87 | { | |
88 | - if (n > sizeof path - 1) | |
89 | - n = sizeof path - 1; | |
90 | - | |
91 | - if (addr == 0) { | |
92 | + if (!addr) { | |
93 | tprintf("NULL"); | |
94 | return; | |
95 | } | |
96 | ||
97 | + /* Cap path length to the path buffer size, | |
98 | + and NUL-terminate the buffer. */ | |
99 | + if (n > sizeof path - 1) | |
100 | + n = sizeof path - 1; | |
101 | path[n] = '\0'; | |
102 | + | |
103 | + /* Fetch one byte more to find out whether path length > n. */ | |
104 | if (umovestr(tcp, addr, n + 1, path) < 0) | |
105 | tprintf("%#lx", addr); | |
106 | else { | |
107 | @@ -515,7 +545,8 @@ printpathn(struct tcb *tcp, long addr, int n) | |
108 | ||
109 | if (trunc) | |
110 | path[n] = '\0'; | |
111 | - if (string_quote(path, outstr, -1, n + 1) || trunc) | |
112 | + (void) string_quote(path, outstr, -1, n + 1); | |
113 | + if (trunc) | |
114 | strcat(outstr, "..."); | |
115 | tprintf("%s", outstr); | |
116 | } | |
117 | @@ -527,6 +558,11 @@ printpath(struct tcb *tcp, long addr) | |
118 | printpathn(tcp, addr, sizeof path - 1); | |
119 | } | |
120 | ||
121 | +/* | |
122 | + * Print string specified by address `addr' and length `len'. | |
123 | + * If `len' < 0, treat the string as a NUL-terminated string. | |
124 | + * If string length exceeds `max_strlen', append `...' to the output. | |
125 | + */ | |
126 | void | |
127 | printstr(struct tcb *tcp, long addr, int len) | |
128 | { | |
129 | @@ -538,32 +574,39 @@ printstr(struct tcb *tcp, long addr, int len) | |
130 | tprintf("NULL"); | |
131 | return; | |
132 | } | |
133 | - if (!str) { | |
134 | - if ((str = malloc(max_strlen + 1)) == NULL | |
135 | - || (outstr = malloc(4*max_strlen | |
136 | - + sizeof "\"\"...")) == NULL) { | |
137 | - fprintf(stderr, "out of memory\n"); | |
138 | - tprintf("%#lx", addr); | |
139 | - return; | |
140 | - } | |
141 | + /* Allocate static buffers if they are not allocated yet. */ | |
142 | + if (!str) | |
143 | + str = malloc(max_strlen + 1); | |
144 | + if (!outstr) | |
145 | + outstr = malloc(4 * max_strlen + sizeof "\"...\""); | |
146 | + if (!str || !outstr) { | |
147 | + fprintf(stderr, "out of memory\n"); | |
148 | + tprintf("%#lx", addr); | |
149 | + return; | |
150 | } | |
151 | ||
152 | if (len < 0) { | |
153 | + /* | |
154 | + * Treat as a NUL-terminated string: fetch one byte more | |
155 | + * because string_quote() quotes one byte less. | |
156 | + */ | |
157 | size = max_strlen + 1; | |
158 | + str[max_strlen] = '\0'; | |
159 | if (umovestr(tcp, addr, size, str) < 0) { | |
160 | tprintf("%#lx", addr); | |
161 | return; | |
162 | } | |
163 | } | |
164 | else { | |
165 | - size = MIN(len, max_strlen + 1); | |
166 | + size = MIN(len, max_strlen); | |
167 | if (umoven(tcp, addr, size, str) < 0) { | |
168 | tprintf("%#lx", addr); | |
169 | return; | |
170 | } | |
171 | } | |
172 | ||
173 | - if (string_quote(str, outstr, len, size)) | |
174 | + if (string_quote(str, outstr, len, size) && | |
175 | + (len < 0 || len > max_strlen)) | |
176 | strcat(outstr, "..."); | |
177 | ||
178 | tprintf("%s", outstr); | |
179 |