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
*/
{
struct loop_info info;
struct loop_info64 info64;
- char *s = alloca((LO_NAME_SIZE + LO_KEY_SIZE) * 4);
if (entering(tcp))
return 0;
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))
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))
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;
", 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;
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;
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;
-
- string_quote(label, outstr, 0, label_len);
- tprintf(", %s}", outstr);
+ tprints(", ");
+ print_quoted_string(label, label_len, 0);
+ tprints("}");
- free(outstr);
return true;
}
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("]");
/*
* 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)
}
}
- *s++ = '\"';
+ if (!(style & QUOTE_OMIT_LEADING_TRAILING_QUOTES))
+ *s++ = '\"';
if (usehex) {
/* Hex-quote the whole string. */
}
}
- *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.
*/
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.
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("...");
}
static char *str = NULL;
static char *outstr;
unsigned int size;
+ unsigned int style;
int ellipsis;
if (!addr) {
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);