Rework string_quote API
string_quote() has proven to be too hard to use, replace it with print_quoted_string() that does memory allocation and prints the result. * defs.h (string_quote): Remove. (QUOTE_0_TERMINATED, QUOTE_OMIT_LEADING_TRAILING_QUOTES): New macros. (print_quoted_string): New prototype. * util.c (string_quote): Make static; take "style" flags instead of "len", treat QUOTE_0_TERMINATED style flag as former (len == -1); add QUOTE_OMIT_LEADING_TRAILING_QUOTES style flag support. (ALLOCA_CUTOFF, use_alloca): New macros. (print_quoted_string): New function. (printpathn, printstr): Update to new API. * loop.c (loop_ioctl): Likewise. * mtd.c (ubi_ioctl): Likewise. * net.c (print_scm_security): Likewise. * socketutils.c (unix_parse_response): Likewise.
This commit is contained in:
parent
a10b6feb44
commit
513e96eb94
6
defs.h
6
defs.h
@ -665,9 +665,13 @@ extern const char *xlookup(const struct xlat *, const unsigned int);
|
||||
extern const char *xlat_search(const struct xlat *, const size_t, const unsigned int);
|
||||
|
||||
extern int string_to_uint(const char *str);
|
||||
extern int string_quote(const char *, char *, long, int);
|
||||
extern int next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits);
|
||||
|
||||
#define QUOTE_0_TERMINATED 0x01
|
||||
#define QUOTE_OMIT_LEADING_TRAILING_QUOTES 0x02
|
||||
|
||||
extern int print_quoted_string(const char *, unsigned int, unsigned int);
|
||||
|
||||
/* a refers to the lower numbered u_arg,
|
||||
* b refers to the higher numbered u_arg
|
||||
*/
|
||||
|
26
loop.c
26
loop.c
@ -39,7 +39,6 @@ loop_ioctl(struct tcb *tcp, const unsigned int code, long arg)
|
||||
{
|
||||
struct loop_info info;
|
||||
struct loop_info64 info64;
|
||||
char *s = alloca((LO_NAME_SIZE + LO_KEY_SIZE) * 4);
|
||||
|
||||
if (entering(tcp))
|
||||
return 0;
|
||||
@ -72,12 +71,14 @@ loop_ioctl(struct tcb *tcp, const unsigned int code, long arg)
|
||||
tprints(", flags=");
|
||||
printflags(loop_flags_options, info.lo_flags, "LO_FLAGS_???");
|
||||
|
||||
string_quote(info.lo_name, s, -1, LO_NAME_SIZE);
|
||||
tprintf(", name=%s", s);
|
||||
tprints(", name=");
|
||||
print_quoted_string(info.lo_name, LO_NAME_SIZE,
|
||||
QUOTE_0_TERMINATED);
|
||||
|
||||
if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
|
||||
string_quote((void *) info.lo_encrypt_key, s, 0, LO_KEY_SIZE);
|
||||
tprintf(", encrypt_key=%s", s);
|
||||
tprints(", encrypt_key=");
|
||||
print_quoted_string((void *) info.lo_encrypt_key,
|
||||
LO_KEY_SIZE, 0);
|
||||
}
|
||||
|
||||
if (!abbrev(tcp))
|
||||
@ -125,14 +126,17 @@ loop_ioctl(struct tcb *tcp, const unsigned int code, long arg)
|
||||
tprints(", flags=");
|
||||
printflags(loop_flags_options, info64.lo_flags, "LO_FLAGS_???");
|
||||
|
||||
string_quote((void *) info64.lo_file_name, s, -1, LO_NAME_SIZE);
|
||||
tprintf(", file_name=%s", s);
|
||||
tprints(", file_name=");
|
||||
print_quoted_string((void *) info64.lo_file_name,
|
||||
LO_NAME_SIZE, QUOTE_0_TERMINATED);
|
||||
|
||||
if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
|
||||
string_quote((void *) info64.lo_crypt_name, s, -1, LO_NAME_SIZE);
|
||||
tprintf(", crypt_name=%s", s);
|
||||
string_quote((void *) info64.lo_encrypt_key, s, 0, LO_KEY_SIZE);
|
||||
tprintf(", encrypt_key=%s", s);
|
||||
tprints(", crypt_name=");
|
||||
print_quoted_string((void *) info64.lo_crypt_name,
|
||||
LO_NAME_SIZE, QUOTE_0_TERMINATED);
|
||||
tprints(", encrypt_key=");
|
||||
print_quoted_string((void *) info64.lo_encrypt_key,
|
||||
LO_KEY_SIZE, 0);
|
||||
}
|
||||
|
||||
if (!abbrev(tcp))
|
||||
|
25
mtd.c
25
mtd.c
@ -262,9 +262,6 @@ ubi_ioctl(struct tcb *tcp, const unsigned int code, long arg)
|
||||
struct ubi_attach_req attach;
|
||||
struct ubi_map_req map;
|
||||
struct ubi_set_vol_prop_req prop;
|
||||
/* 4*(n-1) + 3 for quotes and NUL */
|
||||
char vol_name[(UBI_MAX_VOLUME_NAME + 1) * 4];
|
||||
int ret;
|
||||
|
||||
if (entering(tcp))
|
||||
return 0;
|
||||
@ -278,10 +275,12 @@ ubi_ioctl(struct tcb *tcp, const unsigned int code, long arg)
|
||||
", bytes=%" PRIi64 ", vol_type=", mkvol.vol_id,
|
||||
mkvol.alignment, (int64_t)mkvol.bytes);
|
||||
printxval(ubi_volume_types, mkvol.vol_type, "UBI_???_VOLUME");
|
||||
ret = string_quote(mkvol.name, vol_name, -1,
|
||||
CLAMP(mkvol.name_len, 0, UBI_MAX_VOLUME_NAME));
|
||||
tprintf(", name_len=%" PRIi16 ", name=%s%s",
|
||||
mkvol.name_len, vol_name, ret ? "..." : "");
|
||||
tprintf(", name_len=%" PRIi16 ", name=", mkvol.name_len);
|
||||
if (print_quoted_string(mkvol.name,
|
||||
CLAMP(mkvol.name_len, 0, UBI_MAX_VOLUME_NAME),
|
||||
QUOTE_0_TERMINATED) > 0) {
|
||||
tprints("...");
|
||||
}
|
||||
tprints("}");
|
||||
return 1;
|
||||
|
||||
@ -303,11 +302,15 @@ ubi_ioctl(struct tcb *tcp, const unsigned int code, long arg)
|
||||
for (c = 0; c < CLAMP(rnvol.count, 0, UBI_MAX_RNVOL); ++c) {
|
||||
if (c)
|
||||
tprints(", ");
|
||||
ret = string_quote(rnvol.ents[c].name, vol_name, -1,
|
||||
CLAMP(rnvol.ents[c].name_len, 0, UBI_MAX_VOLUME_NAME));
|
||||
tprintf("{vol_id=%" PRIi32 ", name_len=%" PRIi16
|
||||
", name=%s%s}", rnvol.ents[c].vol_id,
|
||||
rnvol.ents[c].name_len, vol_name, ret ? "..." : "");
|
||||
", name=", rnvol.ents[c].vol_id,
|
||||
rnvol.ents[c].name_len);
|
||||
if (print_quoted_string(rnvol.ents[c].name,
|
||||
CLAMP(rnvol.ents[c].name_len, 0, UBI_MAX_VOLUME_NAME),
|
||||
QUOTE_0_TERMINATED) > 0) {
|
||||
tprints("...");
|
||||
}
|
||||
tprints("}");
|
||||
}
|
||||
tprints("]}");
|
||||
return 1;
|
||||
|
12
net.c
12
net.c
@ -402,17 +402,11 @@ print_scm_security(struct tcb *tcp, size_t cmsg_size, char *ptr, size_t cmsg_len
|
||||
|
||||
const char *label = (const char *) (ptr + cmsg_size);
|
||||
const size_t label_len = cmsg_len - cmsg_size;
|
||||
char *outstr;
|
||||
const size_t alloc_len = 4 * label_len + 3;
|
||||
|
||||
if (label_len != alloc_len / 4 ||
|
||||
!(outstr = malloc(alloc_len)))
|
||||
return false;
|
||||
tprints(", ");
|
||||
print_quoted_string(label, label_len, 0);
|
||||
tprints("}");
|
||||
|
||||
string_quote(label, outstr, 0, label_len);
|
||||
tprintf(", %s}", outstr);
|
||||
|
||||
free(outstr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -252,13 +252,13 @@ unix_parse_response(const char *proto_name, const void *data, int data_len,
|
||||
tprintf("->%u", peer);
|
||||
if (path_len) {
|
||||
if (path[0] == '\0') {
|
||||
char *outstr = alloca(4 * path_len - 1);
|
||||
string_quote(path + 1, outstr, -1, path_len);
|
||||
tprintf(",@%s", outstr);
|
||||
tprints(",@");
|
||||
print_quoted_string(path + 1, path_len,
|
||||
QUOTE_0_TERMINATED);
|
||||
} else {
|
||||
char *outstr = alloca(4 * path_len + 3);
|
||||
string_quote(path, outstr, -1, path_len + 1);
|
||||
tprintf(",%s", outstr);
|
||||
tprints(",");
|
||||
print_quoted_string(path, path_len + 1,
|
||||
QUOTE_0_TERMINATED);
|
||||
}
|
||||
}
|
||||
tprints("]");
|
||||
|
117
util.c
117
util.c
@ -519,24 +519,30 @@ printfd(struct tcb *tcp, int fd)
|
||||
/*
|
||||
* Quote string `instr' of length `size'
|
||||
* Write up to (3 + `size' * 4) bytes to `outstr' buffer.
|
||||
* If `len' is -1, treat `instr' as a NUL-terminated string
|
||||
* and quote at most (`size' - 1) bytes.
|
||||
*
|
||||
* Returns 0 if len == -1 and NUL was seen, 1 otherwise.
|
||||
* Note that if len >= 0, always returns 1.
|
||||
* If QUOTE_0_TERMINATED `style' flag is set,
|
||||
* treat `instr' as a NUL-terminated string,
|
||||
* checking up to (`size' + 1) bytes of `instr'.
|
||||
*
|
||||
* If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
|
||||
* do not add leading and trailing quoting symbols.
|
||||
*
|
||||
* Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
|
||||
* Note that if QUOTE_0_TERMINATED is not set, always returns 1.
|
||||
*/
|
||||
int
|
||||
string_quote(const char *instr, char *outstr, long len, int size)
|
||||
static int
|
||||
string_quote(const char *instr, char *outstr, const unsigned int size,
|
||||
const unsigned int style)
|
||||
{
|
||||
const unsigned char *ustr = (const unsigned char *) instr;
|
||||
char *s = outstr;
|
||||
int usehex, c, i, eol;
|
||||
unsigned int i;
|
||||
int usehex, c, eol;
|
||||
|
||||
eol = 0x100; /* this can never match a char */
|
||||
if (len == -1) {
|
||||
size--;
|
||||
if (style & QUOTE_0_TERMINATED)
|
||||
eol = '\0';
|
||||
}
|
||||
else
|
||||
eol = 0x100; /* this can never match a char */
|
||||
|
||||
usehex = 0;
|
||||
if (xflag > 1)
|
||||
@ -565,7 +571,8 @@ string_quote(const char *instr, char *outstr, long len, int size)
|
||||
}
|
||||
}
|
||||
|
||||
*s++ = '\"';
|
||||
if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
|
||||
*s++ = '\"';
|
||||
|
||||
if (usehex) {
|
||||
/* Hex-quote the whole string. */
|
||||
@ -638,11 +645,12 @@ string_quote(const char *instr, char *outstr, long len, int size)
|
||||
}
|
||||
}
|
||||
|
||||
*s++ = '\"';
|
||||
if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
|
||||
*s++ = '\"';
|
||||
*s = '\0';
|
||||
|
||||
/* Return zero if we printed entire ASCIZ string (didn't truncate it) */
|
||||
if (len == -1 && ustr[i] == '\0') {
|
||||
if (style & QUOTE_0_TERMINATED && ustr[i] == '\0') {
|
||||
/* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
|
||||
* but next char is NUL.
|
||||
*/
|
||||
@ -652,12 +660,70 @@ string_quote(const char *instr, char *outstr, long len, int size)
|
||||
return 1;
|
||||
|
||||
asciz_ended:
|
||||
*s++ = '\"';
|
||||
if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
|
||||
*s++ = '\"';
|
||||
*s = '\0';
|
||||
/* Return zero: we printed entire ASCIZ string (didn't truncate it) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef ALLOCA_CUTOFF
|
||||
# define ALLOCA_CUTOFF 4032
|
||||
#endif
|
||||
#define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
|
||||
|
||||
/*
|
||||
* Quote string `str' of length `size' and print the result.
|
||||
*
|
||||
* If QUOTE_0_TERMINATED `style' flag is set,
|
||||
* treat `str' as a NUL-terminated string and
|
||||
* quote at most (`size' - 1) bytes.
|
||||
*
|
||||
* If QUOTE_OMIT_LEADING_TRAILING_QUOTES `style' flag is set,
|
||||
* do not add leading and trailing quoting symbols.
|
||||
*
|
||||
* Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen, 1 otherwise.
|
||||
* Note that if QUOTE_0_TERMINATED is not set, always returns 1.
|
||||
*/
|
||||
int
|
||||
print_quoted_string(const char *str, unsigned int size,
|
||||
const unsigned int style)
|
||||
{
|
||||
char *buf;
|
||||
char *outstr;
|
||||
unsigned int alloc_size;
|
||||
int rc;
|
||||
|
||||
if (size && style & QUOTE_0_TERMINATED)
|
||||
--size;
|
||||
|
||||
alloc_size = 4 * size;
|
||||
if (alloc_size / 4 != size) {
|
||||
error_msg("Out of memory");
|
||||
tprints("???");
|
||||
return -1;
|
||||
}
|
||||
alloc_size += 1 + (style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2);
|
||||
|
||||
if (use_alloca(alloc_size)) {
|
||||
outstr = alloca(alloc_size);
|
||||
buf = NULL;
|
||||
} else {
|
||||
outstr = buf = malloc(alloc_size);
|
||||
if (!buf) {
|
||||
error_msg("Out of memory");
|
||||
tprints("???");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
rc = string_quote(str, outstr, size, style);
|
||||
tprints(outstr);
|
||||
|
||||
free(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print path string specified by address `addr' and length `n'.
|
||||
* If path length exceeds `n', append `...' to the output.
|
||||
@ -682,13 +748,8 @@ printpathn(struct tcb *tcp, long addr, unsigned int n)
|
||||
if (nul_seen < 0)
|
||||
tprintf("%#lx", addr);
|
||||
else {
|
||||
char *outstr;
|
||||
|
||||
path[n] = '\0';
|
||||
n++;
|
||||
outstr = alloca(4 * n); /* 4*(n-1) + 3 for quotes and NUL */
|
||||
string_quote(path, outstr, -1, n);
|
||||
tprints(outstr);
|
||||
path[n++] = '\0';
|
||||
print_quoted_string(path, n, QUOTE_0_TERMINATED);
|
||||
if (!nul_seen)
|
||||
tprints("...");
|
||||
}
|
||||
@ -712,6 +773,7 @@ printstr(struct tcb *tcp, long addr, long len)
|
||||
static char *str = NULL;
|
||||
static char *outstr;
|
||||
unsigned int size;
|
||||
unsigned int style;
|
||||
int ellipsis;
|
||||
|
||||
if (!addr) {
|
||||
@ -732,31 +794,32 @@ printstr(struct tcb *tcp, long addr, long len)
|
||||
die_out_of_memory();
|
||||
}
|
||||
|
||||
size = max_strlen;
|
||||
if (len == -1) {
|
||||
/*
|
||||
* Treat as a NUL-terminated string: fetch one byte more
|
||||
* because string_quote() quotes one byte less.
|
||||
* because string_quote may look one byte ahead.
|
||||
*/
|
||||
size = max_strlen + 1;
|
||||
if (umovestr(tcp, addr, size, str) < 0) {
|
||||
if (umovestr(tcp, addr, size + 1, str) < 0) {
|
||||
tprintf("%#lx", addr);
|
||||
return;
|
||||
}
|
||||
style = QUOTE_0_TERMINATED;
|
||||
}
|
||||
else {
|
||||
size = max_strlen;
|
||||
if (size > (unsigned long)len)
|
||||
size = (unsigned long)len;
|
||||
if (umoven(tcp, addr, size, str) < 0) {
|
||||
tprintf("%#lx", addr);
|
||||
return;
|
||||
}
|
||||
style = 0;
|
||||
}
|
||||
|
||||
/* 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, len, size) &&
|
||||
ellipsis = (string_quote(str, outstr, size, style) &&
|
||||
(len < 0 || (unsigned long) len > max_strlen));
|
||||
|
||||
tprints(outstr);
|
||||
|
Loading…
Reference in New Issue
Block a user