Skip to content

Commit 522ddb0

Browse files
committed
Fix a crash with long diagnostic messages
2048 characters is apparently not enough for diagnostic messages :). Now it uses dynamically allocated strings instead so we can handle "arbitrarily" long messages.
1 parent 245ef8c commit 522ddb0

2 files changed

Lines changed: 26 additions & 17 deletions

File tree

src/dged/json.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ struct s8 unescape_json_string(struct s8 input) {
9999
}
100100

101101
escape = false;
102-
uint8_t *buf = calloc(new_size, 1);
102+
uint8_t *buf = calloc(new_size + 1, 1);
103103
size_t bufi = 0;
104104
for (size_t bi = 0; bi < input.l; ++bi) {
105105
uint8_t b = input.s[bi];
@@ -152,6 +152,8 @@ struct s8 unescape_json_string(struct s8 input) {
152152
bufi += skip;
153153
}
154154

155+
buf[new_size] = '\0';
156+
155157
return (struct s8){
156158
.s = buf,
157159
.l = new_size,
@@ -177,7 +179,7 @@ struct s8 escape_json_string(struct s8 input) {
177179
}
178180
}
179181

180-
uint8_t *buf = calloc(new_size, 1);
182+
uint8_t *buf = calloc(new_size + 1, 1);
181183
size_t bufi = 0;
182184
for (size_t bi = 0; bi < input.l; ++bi) {
183185
uint8_t b = input.s[bi];
@@ -223,6 +225,8 @@ struct s8 escape_json_string(struct s8 input) {
223225
}
224226
}
225227

228+
buf[new_size] = '\0';
229+
226230
return (struct s8){
227231
.s = buf,
228232
.l = new_size,

src/main/lsp/diagnostics.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "dged/location.h"
1010
#include "dged/lsp.h"
1111
#include "dged/minibuffer.h"
12+
#include "dged/s8.h"
1213
#include "dged/vec.h"
1314
#include "main/bindings.h"
1415
#include "main/lsp.h"
@@ -149,7 +150,6 @@ static struct buffer *update_diagnostics_buffer(struct lsp_server *server,
149150
struct buffers *buffers,
150151
diagnostic_vec diagnostics,
151152
struct buffer *buffer) {
152-
char buf[2048];
153153
struct buffer *db = buffers_find(buffers, DIAGNOSTIC_BUFNAME);
154154
if (db == NULL) {
155155
struct buffer buf = buffer_create(DIAGNOSTIC_BUFNAME);
@@ -181,44 +181,46 @@ static struct buffer *update_diagnostics_buffer(struct lsp_server *server,
181181
buffer_clear_text_properties(db);
182182

183183
g_active_diagnostic.buffer = buffer;
184-
ssize_t len = snprintf(buf, 2048, "Diagnostics for %s:\n\n", buffer->name);
185-
if (len != -1) {
186-
buffer_add(db, buffer_end(db), (uint8_t *)buf, len);
184+
struct s8 header = s8from_fmt("Diagnostics for %s:\n\n", buffer->name);
185+
if (header.l > 0) {
186+
buffer_add(db, buffer_end(db), header.s, header.l);
187187
buffer_add_text_property(
188188
db, (struct location){.line = 0, .col = 0},
189189
(struct location){.line = 1, .col = 0},
190190
(struct text_property){.type = TextProperty_Colors,
191191
.data.colors.underline = true});
192192
}
193+
s8delete(header);
193194

194195
VEC_DESTROY(&g_active_diagnostic.diag_regions);
195196
VEC_INIT(&g_active_diagnostic.diag_regions, VEC_SIZE(&diagnostics));
196197
VEC_FOR_EACH(&diagnostics, struct diagnostic * diag) {
197198
struct location start = buffer_end(db);
198-
char src[128];
199-
size_t srclen = snprintf(src, 128, "%.*s%s", diag->source.l, diag->source.s,
200-
diag->source.l > 0 ? ": " : "");
199+
200+
struct s8 src = s8from_fmt("%s%s", s8ascstr(diag->source),
201+
diag->source.l > 0 ? ": " : "");
202+
201203
const char *severity_str = diag_severity_to_str(diag->severity);
202204
size_t severity_str_len = strlen(severity_str);
203205
struct region reg = lsp_range_to_coordinates(server, buffer, diag->region);
204-
len = snprintf(buf, 2048,
205-
"%s%s [%d, %d]: %.*s\n-------------------------------", src,
206-
severity_str, reg.begin.line + 1, reg.begin.col,
207-
diag->message.l, diag->message.s);
206+
struct s8 text =
207+
s8from_fmt("%s%s [%d, %d]: %s\n-------------------------------",
208+
s8ascstr(src), severity_str, reg.begin.line + 1,
209+
reg.begin.col, s8ascstr(diag->message));
208210

209-
if (len != -1) {
210-
buffer_add(db, buffer_end(db), (uint8_t *)buf, len);
211+
if (text.l > 0) {
212+
buffer_add(db, buffer_end(db), text.s, text.l);
211213

212214
struct location srcend = start;
213-
srcend.col += srclen - 3;
215+
srcend.col += src.l - 3;
214216
buffer_add_text_property(
215217
db, start, srcend,
216218
(struct text_property){.type = TextProperty_Colors,
217219
.data.colors.underline = true});
218220

219221
uint32_t color = diag_severity_color(diag->severity);
220222
struct location sevstart = start;
221-
sevstart.col += srclen;
223+
sevstart.col += src.l;
222224
struct location sevend = sevstart;
223225
sevend.col += severity_str_len;
224226
buffer_add_text_property(
@@ -235,6 +237,9 @@ static struct buffer *update_diagnostics_buffer(struct lsp_server *server,
235237

236238
buffer_newline(db, buffer_end(db));
237239
}
240+
241+
s8delete(text);
242+
s8delete(src);
238243
}
239244

240245
buffer_set_readonly(db, true);

0 commit comments

Comments
 (0)