1 /*
2 * Copyright (c) 2016-2021 The strace developers.
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 #include "tests.h"
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 /*
15 * Based on string_quote() from util.c.
16 * Assumes instr is NUL-terminated.
17 */
18
19 void
20 print_quoted_string_ex(const char *instr, bool quote, const char *escape_chars)
21 {
22 print_quoted_memory_ex(instr, strlen(instr), quote, escape_chars);
23 }
24
25 void
26 print_quoted_string(const char *instr)
27 {
28 print_quoted_memory(instr, strlen(instr));
29 }
30
31 void
32 print_quoted_cstring(const char *instr, const size_t size)
33 {
34 const size_t len = strnlen(instr, size);
35 if (len < size) {
36 print_quoted_memory(instr, len);
37 } else {
38 print_quoted_memory(instr, size - 1);
39 printf("...");
40 }
41 }
42
43 void
44 print_quoted_stringn(const char *instr, const size_t size)
45 {
46 const size_t len = strnlen(instr, size);
47 if (len < size) {
48 print_quoted_memory(instr, len);
49 } else {
50 print_quoted_memory(instr, size);
51 printf("...");
52 }
53 }
54
55 static void
56 print_octal(unsigned char c, char next)
57 {
58 putchar('\\');
59
60 char c1 = '0' + (c & 0x7);
61 char c2 = '0' + ((c >> 3) & 0x7);
62 char c3 = '0' + (c >> 6);
63
64 if (next >= '0' && next <= '7') {
65 /* Print \octal */
66 putchar(c3);
67 putchar(c2);
68 } else {
69 /* Print \[[o]o]o */
70 if (c3 != '0')
71 putchar(c3);
72 if (c3 != '0' || c2 != '0')
73 putchar(c2);
74 }
75 putchar(c1);
76 }
77
78 void
79 print_quoted_memory_ex(const void *const instr, const size_t len,
80 bool quote, const char *escape_chars)
81 {
82 const unsigned char *str = (const unsigned char *) instr;
83
84 if (quote)
85 putchar('"');
86
87 for (size_t i = 0; i < len; ++i) {
88 const int c = str[i];
89 switch (c) {
90 case '\"':
91 printf("\\\"");
92 break;
93 case '\\':
94 printf("\\\\");
95 break;
96 case '\f':
97 printf("\\f");
98 break;
99 case '\n':
100 printf("\\n");
101 break;
102 case '\r':
103 printf("\\r");
104 break;
105 case '\t':
106 printf("\\t");
107 break;
108 case '\v':
109 printf("\\v");
110 break;
111 default:
112 if (c >= ' ' && c <= 0x7e &&
113 !(escape_chars && strchr(escape_chars, c))) {
114 putchar(c);
115 } else {
116 print_octal(c,
117 i < (len - 1) ? str[i + 1] : 0);
118 }
119
120 break;
121 }
122 }
123
124 if (quote)
125 putchar('"');
126 }
127
128 void
129 print_quoted_memory(const void *const instr, const size_t len)
130 {
131 print_quoted_memory_ex(instr, len, true, NULL);
132 }
133
134 void
135 print_quoted_hex(const void *const instr, const size_t len)
136 {
137 const unsigned char *str = instr;
138
139 printf("\"");
140 for (size_t i = 0; i < len; ++i)
141 printf("\\x%02x", str[i]);
142 printf("\"");
143 }