dte test coverage


Directory: ./
File: src/command/serialize.c
Date: 2025-11-12 12:04:10
Coverage Exec Excl Total
Lines: 100.0% 48 0 48
Functions: 100.0% 3 0 3
Branches: 96.9% 31 0 32

Line Branch Exec Source
1 #include <string.h>
2 #include "serialize.h"
3 #include "util/ascii.h"
4 #include "util/numtostr.h"
5
6 typedef enum {
7 NO_QUOTE,
8 SINGLE_QUOTE,
9 DOUBLE_QUOTE,
10 } SerializeType;
11
12 static const char escmap[] = {
13 [0x07] = 'a',
14 [0x08] = 'b',
15 [0x09] = 't',
16 [0x0A] = 'n',
17 [0x0B] = 'v',
18 [0x0C] = 'f',
19 [0x0D] = 'r',
20 [0x1B] = 'e',
21 ['"'] = '"',
22 ['\\'] = '\\',
23 };
24
25 13 static void string_append_dquoted_arg(String *s, StringView arg)
26 {
27 13 string_append_byte(s, '"');
28
29
2/2
✓ Branch 12 → 4 taken 473 times.
✓ Branch 12 → 13 taken 13 times.
486 for (size_t i = 0, n = arg.length; i < n; i++) {
30 473 char *buf = string_reserve_space(s, 4);
31 473 size_t pos = 0;
32 473 unsigned char ch = arg.data[i];
33
4/4
✓ Branch 5 → 6 taken 133 times.
✓ Branch 5 → 8 taken 340 times.
✓ Branch 6 → 7 taken 23 times.
✓ Branch 6 → 8 taken 110 times.
473 if (unlikely(ch < sizeof(escmap) && escmap[ch])) {
34 23 buf[pos++] = '\\';
35 23 ch = escmap[ch];
36
2/2
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 11 taken 448 times.
450 } else if (unlikely(ascii_iscntrl(ch))) {
37 2 pos += copyliteral(buf + pos, "\\x");
38 2 buf[pos++] = hextable[(ch >> 4) & 0xF];
39 2 ch = hextable[ch & 0xF];
40 }
41 473 buf[pos++] = ch;
42 473 s->len += pos;
43 }
44
45 13 string_append_byte(s, '"');
46 13 }
47
48 1268 static SerializeType get_serialize_type(const char *arg, size_t n)
49 {
50 1268 SerializeType type = NO_QUOTE;
51
2/2
✓ Branch 10 → 3 taken 14357 times.
✓ Branch 10 → 11 taken 1255 times.
15612 for (size_t i = 0; i < n; i++) {
52 14357 const unsigned char c = arg[i];
53
3/4
✓ Branch 3 → 4 taken 14344 times.
✓ Branch 3 → 11 taken 13 times.
✓ Branch 4 → 5 taken 14344 times.
✗ Branch 4 → 11 not taken.
14357 if (c == '\'' || c < 0x20 || c == 0x7F) {
54 return DOUBLE_QUOTE;
55 }
56
6/6
✓ Branch 5 → 6 taken 13952 times.
✓ Branch 5 → 8 taken 392 times.
✓ Branch 6 → 7 taken 13925 times.
✓ Branch 6 → 8 taken 27 times.
✓ Branch 7 → 8 taken 44 times.
✓ Branch 7 → 9 taken 13881 times.
14344 if (c == ' ' || c == '"' || c == '$' || c == ';' || c == '\\') {
57 463 type = SINGLE_QUOTE;
58 }
59 }
60 return type;
61 }
62
63 // Append `arg` to `s`, escaping dterc(5) special characters and/or
64 // quoting as appropriate, so that the appended string round-trips
65 // back to `arg` when passed to parse_command_arg(). If escape_tilde
66 // is true, any leading "~/" substring will be escaped, so as to not
67 // expand to $HOME/.
68 1276 void string_append_escaped_arg_sv(String *s, StringView arg, bool escape_tilde)
69 {
70 1276 char *buf = string_reserve_space(s, arg.length + STRLEN("~/''"));
71
2/2
✓ Branch 3 → 4 taken 8 times.
✓ Branch 3 → 6 taken 1268 times.
1276 if (arg.length == 0) {
72 8 s->len += copyliteral(buf, "''");
73 8 return;
74 }
75
76 1268 bool has_tilde_slash_prefix = strview_has_prefix(arg, "~/");
77
2/2
✓ Branch 7 → 8 taken 7 times.
✓ Branch 7 → 10 taken 1261 times.
1268 if (has_tilde_slash_prefix && !escape_tilde) {
78 // Print "~/" and skip past it, so it doesn't get quoted
79 7 size_t skip = copyliteral(buf, "~/");
80 7 buf += skip;
81 7 s->len += skip;
82 7 strview_remove_prefix(&arg, skip);
83 }
84
85 1268 SerializeType type = get_serialize_type(arg.data, arg.length);
86
2/2
✓ Branch 10 → 11 taken 13 times.
✓ Branch 10 → 13 taken 1255 times.
1268 if (type == DOUBLE_QUOTE) {
87 13 string_append_dquoted_arg(s, arg);
88 13 return;
89 }
90
91 1255 size_t n = 0;
92
2/2
✓ Branch 13 → 14 taken 165 times.
✓ Branch 13 → 15 taken 1090 times.
1255 if (type == SINGLE_QUOTE) {
93 165 buf[n++] = '\'';
94
2/2
✓ Branch 15 → 16 taken 2 times.
✓ Branch 15 → 17 taken 1088 times.
1090 } else if (has_tilde_slash_prefix && escape_tilde) {
95 2 buf[n++] = '\\';
96 }
97 1255 n += copystrn(buf + n, arg.data, arg.length);
98
2/2
✓ Branch 18 → 19 taken 165 times.
✓ Branch 18 → 20 taken 1090 times.
1255 if (type == SINGLE_QUOTE) {
99 165 buf[n++] = '\'';
100 }
101 1255 s->len += n;
102 }
103