Skip to content

Commit 04b823f

Browse files
authored
Merge pull request #593 from jnovy/493
Fix JSON parsing error in console file descriptor communication
2 parents e579e76 + 49017b5 commit 04b823f

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

src/cmsg.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,16 @@ struct file_t recvfd(int sockfd)
133133
msg.msg_controllen = sizeof(u.buf);
134134

135135
ssize_t ret = recvmsg(sockfd, &msg, 0);
136-
if (ret < 0)
136+
if (ret < 0) {
137+
/* Add specific error information for debugging console fd issues */
138+
fprintf(stderr, "recvfd: recvmsg failed: %m (sockfd=%d)\n", sockfd);
137139
goto err;
140+
}
141+
if (ret >= TAG_BUFFER) {
142+
fprintf(stderr, "recvfd: received data too large: %zd >= %d\n", ret, TAG_BUFFER);
143+
errno = EMSGSIZE;
144+
goto err;
145+
}
138146
file.name[ret] = '\0';
139147

140148
/* Shrink the buffer to what is effectively used. */

src/parent_pipe_fd.c

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,24 @@ void write_or_close_sync_fd(int *fd, int res, const char *message)
4343
return;
4444

4545
_cleanup_free_ char *json = NULL;
46-
if (message) {
46+
if (message && strlen(message) > 0) {
4747
_cleanup_free_ char *escaped_message = escape_json_string(message);
48-
json = g_strdup_printf("{\"%s\": %d, \"message\": \"%s\"}\n", res_key, res, escaped_message);
48+
if (escaped_message == NULL) {
49+
/* Fallback to JSON without message if escaping fails */
50+
json = g_strdup_printf("{\"%s\": %d}\n", res_key, res);
51+
} else {
52+
json = g_strdup_printf("{\"%s\": %d, \"message\": \"%s\"}\n", res_key, res, escaped_message);
53+
}
4954
} else {
5055
json = g_strdup_printf("{\"%s\": %d}\n", res_key, res);
5156
}
5257

58+
/* Ensure we have valid JSON before attempting to write */
59+
if (json == NULL) {
60+
/* Fallback to minimal valid JSON */
61+
json = g_strdup_printf("{\"%s\": %d}\n", res_key, res);
62+
}
63+
5364
len = strlen(json);
5465
if (write_all(*fd, json, len) != len) {
5566
if (errno == EPIPE) {
@@ -63,21 +74,49 @@ void write_or_close_sync_fd(int *fd, int res, const char *message)
6374

6475
static char *escape_json_string(const char *str)
6576
{
77+
if (str == NULL) {
78+
return NULL;
79+
}
80+
81+
size_t str_len = strlen(str);
82+
if (str_len == 0) {
83+
return g_strdup("");
84+
}
85+
6686
const char *p = str;
67-
GString *escaped = g_string_sized_new(strlen(str));
87+
GString *escaped = g_string_sized_new(str_len * 2); /* Pre-allocate extra space for escaping */
88+
89+
if (escaped == NULL) {
90+
return NULL;
91+
}
6892

6993
while (*p != 0) {
70-
char c = *p++;
94+
unsigned char c = (unsigned char)*p++;
95+
96+
/* Handle standard JSON escape sequences */
7197
if (c == '\\' || c == '"') {
7298
g_string_append_c(escaped, '\\');
7399
g_string_append_c(escaped, c);
100+
} else if (c == '/') {
101+
g_string_append_printf(escaped, "\\/");
74102
} else if (c == '\n') {
75103
g_string_append_printf(escaped, "\\n");
104+
} else if (c == '\r') {
105+
g_string_append_printf(escaped, "\\r");
76106
} else if (c == '\t') {
77107
g_string_append_printf(escaped, "\\t");
78-
} else if ((c > 0 && c < 0x1f) || c == 0x7f) {
79-
g_string_append_printf(escaped, "\\u00%02x", (guint)c);
108+
} else if (c == '\b') {
109+
g_string_append_printf(escaped, "\\b");
110+
} else if (c == '\f') {
111+
g_string_append_printf(escaped, "\\f");
112+
} else if (c < 0x20 || c == 0x7f) {
113+
/* Escape control characters */
114+
g_string_append_printf(escaped, "\\u00%02x", c);
115+
} else if (c >= 0x80) {
116+
/* For non-ASCII characters, pass through as-is for UTF-8 compatibility */
117+
g_string_append_c(escaped, c);
80118
} else {
119+
/* Regular ASCII characters */
81120
g_string_append_c(escaped, c);
82121
}
83122
}

0 commit comments

Comments
 (0)