overflow errors

This commit is contained in:
2026-06-03 14:09:01 +02:00
parent 564292b03e
commit 23f7701eb9
12 changed files with 240 additions and 157 deletions
+1 -1
View File
@@ -7,6 +7,6 @@
void abAppend(struct abuf *ab, const char *s, int len); void abAppend(struct abuf *ab, const char *s, int len);
void abFree(const struct abuf *ab); void abFree(struct abuf *ab);
#endif // APPEND_BUFFER_H_ #endif // APPEND_BUFFER_H_
+4
View File
@@ -13,6 +13,10 @@
#define TAB "\t" #define TAB "\t"
#define SPACE "\x20" #define SPACE "\x20"
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
/* Uncomment to see debug logs on stderr */ /* Uncomment to see debug logs on stderr */
#define APP_DEBUG #define APP_DEBUG
+17 -20
View File
@@ -28,42 +28,39 @@
struct editorConfig E; struct editorConfig E;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Get HOME with NULL check
const char *home = getenv("HOME");
if (!home) {
fprintf(stderr, "Error: HOME environment variable not set\n");
return 1;
}
char * splash_screen = strdup(getenv("HOME")); // Allocate and build splash screen path safely
int home_path_len = (int) strlen(splash_screen); char *splash_screen;
char * splash_screen_relative_path = strdup("/.beluga/assets/beluga.txt"); if (asprintf(&splash_screen, "%s/.beluga/assets/beluga.txt", home) == -1) {
int splash_screen_relative_path_len = (int) strlen(splash_screen_relative_path); fprintf(stderr, "Error: Failed to allocate splash screen path\n");
return 1;
signal(SIGPIPE, SIG_IGN); // don't die on broken pipe, just get EPIPE from write() }
signal(SIGPIPE, SIG_IGN);
enableRawMode(); enableRawMode();
initEditor(); initEditor();
EditorPane *active = splitScreenGetActivePane(); EditorPane *active = splitScreenGetActivePane();
struct buffer_t *buf; struct buffer_t *buf;
splash_screen = realloc(splash_screen, sizeof(char) * (home_path_len + splash_screen_relative_path_len + 1));
strcat(splash_screen, "/.beluga/assets/beluga.txt");
free(splash_screen_relative_path);
appDebug("splash : %s\n", splash_screen); appDebug("splash : %s\n", splash_screen);
active->buffer_id = bufferCreate(splash_screen, READ_ONLY); active->buffer_id = bufferCreate(splash_screen, READ_ONLY);
if (argc >= 2) { if (argc >= 2) {
if (E.constantes.LSP) {
}
active->buffer_id = bufferCreate(argv[1], READ_AND_WRITE); active->buffer_id = bufferCreate(argv[1], READ_AND_WRITE);
buf = &E.buffers[active->buffer_id]; buf = &E.buffers[active->buffer_id];
appDebug("project root : %s\n", dirname(buf->fullname));
appDebug("peoject root : %s\n", dirname(buf->fullname));
} }
free(splash_screen);
free(splash_screen); // Now guaranteed safe
editorSetStatusMessage("HELP: Ctrl-x Ctrl-s = save | Ctrl-x Ctrl-c = quit"); editorSetStatusMessage("HELP: Ctrl-x Ctrl-s = save | Ctrl-x Ctrl-c = quit");
while (1) { while (1) {
editorRefreshScreen(); editorRefreshScreen();
editorProcessKeypress(); editorProcessKeypress();
+5 -1
View File
@@ -11,4 +11,8 @@ void abAppend(struct abuf *ab, const char *s, int len) {
ab->len += len; ab->len += len;
} }
void abFree(const struct abuf *ab) { free(ab->b); } void abFree(struct abuf *ab) {
free(ab->b);
ab->b = NULL;
ab->len = 0;
}
+55 -23
View File
@@ -63,7 +63,7 @@ struct buffer_t* bufferFindById(int buffer_id)
int bufferCreate(const char* path, enum bufferStatus_e state) int bufferCreate(const char* path, enum bufferStatus_e state)
{ {
appDebug("Creating new buffer"); appDebug("Creating new buffer");
char *filename = basename((char *) path); char* filename = basename((char*)path);
// Check if file is already open // Check if file is already open
const int existing_id = bufferFindByFilename(path); const int existing_id = bufferFindByFilename(path);
if (existing_id != -1) if (existing_id != -1)
@@ -81,7 +81,16 @@ int bufferCreate(const char* path, enum bufferStatus_e state)
struct buffer_t* new_buf = &E.buffers[E.number_of_buffer]; struct buffer_t* new_buf = &E.buffers[E.number_of_buffer];
new_buf->buffer_id = E.number_of_buffer; new_buf->buffer_id = E.number_of_buffer;
new_buf->filename = strdup(filename); new_buf->filename = strdup(filename);
if (!new_buf->filename)
{
return -1;
}
new_buf->fullname = malloc(1024 * sizeof(char)); new_buf->fullname = malloc(1024 * sizeof(char));
if (!new_buf->fullname)
{
free(new_buf->filename);
return -1;
}
realpath(path, new_buf->fullname); realpath(path, new_buf->fullname);
new_buf->path = dirname(new_buf->fullname); new_buf->path = dirname(new_buf->fullname);
new_buf->type = FILE_BUFF; new_buf->type = FILE_BUFF;
@@ -98,8 +107,7 @@ int bufferCreate(const char* path, enum bufferStatus_e state)
{ {
if (E.lsp_client->state == LSP_SHUTDOWN) if (E.lsp_client->state == LSP_SHUTDOWN)
lspStart(E.lsp_client, dirname(new_buf->path)); lspStart(E.lsp_client, dirname(new_buf->path));
while (E.lsp_client->state != LSP_READY) while (E.lsp_client->state != LSP_READY);
;
lspDidOpen(E.lsp_client, new_buf); lspDidOpen(E.lsp_client, new_buf);
} }
@@ -301,7 +309,7 @@ void bufferFind(struct buffer_t* buf)
if (query == NULL) if (query == NULL)
return; return;
int i; int i;
for (i = buf->y+1; i < buf->numrows; i++) for (i = buf->y + 1; i < buf->numrows; i++)
{ {
row_t* row = &buf->row[i]; row_t* row = &buf->row[i];
char* match = strstr(row->chars, query); char* match = strstr(row->chars, query);
@@ -337,23 +345,25 @@ void bufferFindReverse(struct buffer_t* buf)
free(query); free(query);
} }
void bufferInsertRow(struct buffer_t *buffer, int at, char *s, size_t len) { void bufferInsertRow(struct buffer_t* buffer, int at, char* s, size_t len)
{
if (at < 0 || at > buffer->numrows) if (at < 0 || at > buffer->numrows)
return; return;
row_t *tmp = realloc(buffer->row, sizeof(row_t) * (buffer->numrows + 1)); row_t* tmp = realloc(buffer->row, sizeof(row_t) * (buffer->numrows + 1));
if (!tmp) if (!tmp)
return; return;
buffer->row = tmp; buffer->row = tmp;
/* Shift existing rows to make room at 'at' — no at++ */ /* Shift existing rows to make room at 'at' — no at++ */
if (at < buffer->numrows) { if (at < buffer->numrows)
{
memmove(&buffer->row[at + 1], &buffer->row[at], memmove(&buffer->row[at + 1], &buffer->row[at],
sizeof(row_t) * (buffer->numrows - at)); /* not -at+1 */ sizeof(row_t) * (buffer->numrows - at)); /* not -at+1 */
} }
buffer->row[at].size = (int) len; buffer->row[at].size = (int)len;
buffer->row[at].cap = (int) len + 1; buffer->row[at].cap = (int)len + 1;
buffer->row[at].chars = malloc(len + 1); buffer->row[at].chars = malloc(len + 1);
if (!buffer->row[at].chars) if (!buffer->row[at].chars)
return; return;
@@ -364,24 +374,41 @@ void bufferInsertRow(struct buffer_t *buffer, int at, char *s, size_t len) {
buffer->dirty++; buffer->dirty++;
} }
void bufferFreeRow(row_t *row) { free(row->chars); } void bufferFreeRow(row_t* row) { free(row->chars); }
/** /**
* \fn editorRowInsertChar(erow *row, int at, int c) * \fn editorRowInsertChar(erow *row, int at, int c)
* \param at Index of where we want to insert the char */ * \param at Index of where we want to insert the char */
void bufferRowInsertBytes(struct buffer_t *buffer, row_t *row, int at, void bufferRowInsertBytes(struct buffer_t* buffer, row_t* row, int at,
const char *src, int n) { const char* src, int n)
{
if (buffer->state == READ_ONLY) if (buffer->state == READ_ONLY)
return; return;
if (row->size + n + 1 > row->cap) { if (at < 0 || at > row->size)
row->cap = (row->size + n + 1) * 2; {
row->chars = realloc(row->chars, row->cap); return;
}
if (row->size + n + 1 > row->cap)
{
size_t new_cap = row->cap == 0 ? 128 : row->cap * 2;
while (new_cap < row->size + n + 1) {
new_cap *= 2;
}
char *new_chars = realloc(row->chars, new_cap);
if (!new_chars) {
return; // Allocation failed
}
row->chars = new_chars;
row->cap = (int) new_cap;
} }
memmove(row->chars + at + n, row->chars + at, row->size - at); memmove(row->chars + at + n, row->chars + at, row->size - at);
// Copy new bytes
memcpy(row->chars + at, src, n); memcpy(row->chars + at, src, n);
row->size += n; row->size += n;
row->chars = realloc(row->chars, row->size + 2);
row->chars[row->size] = '\0';
++buffer->dirty; ++buffer->dirty;
} }
@@ -390,7 +417,8 @@ void bufferRowInsertBytes(struct buffer_t *buffer, row_t *row, int at,
* \brief Delete the a char at the chosen position on the given row * \brief Delete the a char at the chosen position on the given row
* \param at Index of the char to delete * \param at Index of the char to delete
* \param row Row on operation is made */ * \param row Row on operation is made */
void bufferRowDelByte(struct buffer_t *buffer, row_t *row, int at, int n) { void bufferRowDelByte(struct buffer_t* buffer, row_t* row, int at, int n)
{
if (buffer->state == READ_ONLY) if (buffer->state == READ_ONLY)
return; return;
if (at < 0 || at >= row->size) if (at < 0 || at >= row->size)
@@ -461,18 +489,22 @@ void bufferDelBytes(void)
} }
} }
void bufferInsertNewLine(void) { void bufferInsertNewLine(void)
{
appDebug("Inserting new line\n"); appDebug("Inserting new line\n");
EditorPane *active = splitScreenGetActivePane(); EditorPane* active = splitScreenGetActivePane();
struct buffer_t *buf = bufferFindById(active->buffer_id); struct buffer_t* buf = bufferFindById(active->buffer_id);
appDebug("buf x %d\n", buf->x); appDebug("buf x %d\n", buf->x);
if (buf->y >= buf->numrows) { if (buf->y >= buf->numrows)
{
/* Cursor is past the last row: just append a blank line */ /* Cursor is past the last row: just append a blank line */
bufferInsertRow(buf, buf->numrows, "", 0); bufferInsertRow(buf, buf->numrows, "", 0);
} else { }
row_t *row = &buf->row[buf->y]; else
{
row_t* row = &buf->row[buf->y];
/* Insert the tail (from cursor to end) as a new row below */ /* Insert the tail (from cursor to end) as a new row below */
bufferInsertRow(buf, buf->y + 1, &row->chars[buf->x], row->size - buf->x); bufferInsertRow(buf, buf->y + 1, &row->chars[buf->x], row->size - buf->x);
+30 -20
View File
@@ -137,24 +137,27 @@ void bFree_structs(void)
{ {
int i, j; int i, j;
free(E.prefix); free(E.prefix);
for (i = 0; i < E.number_of_keybinds; ++i) for (i = 0; i < E.number_of_keybinds; ++i) {
{
free(E.key_binds[i].key_sequence); free(E.key_binds[i].key_sequence);
E.key_binds[i].key_sequence = NULL;
} }
free(E.key_binds); free(E.key_binds);
// bFree layout E.key_binds = NULL;
free(E.layout.panes); E.number_of_keybinds = 0;
// bFree buffers // Similar fix for buffers
for (i = 0; i < E.number_of_buffer; ++i) for (i = 0; i < E.number_of_buffer; ++i) {
{
free(E.buffers[i].filename); free(E.buffers[i].filename);
for (j = 0; j < E.buffers[i].numrows; ++j) E.buffers[i].filename = NULL;
{ for (j = 0; j < E.buffers[i].numrows; ++j) {
free(E.buffers[i].row[j].chars); free(E.buffers[i].row[j].chars);
E.buffers[i].row[j].chars = NULL;
} }
free(E.buffers[i].row); free(E.buffers[i].row);
E.buffers[i].row = NULL;
} }
// bFree layout
free(E.layout.panes);
free(E.init_file_path); free(E.init_file_path);
fclose(E.fd_init_file); fclose(E.fd_init_file);
@@ -187,7 +190,7 @@ Lisp editorQuit(Lisp args, LispError* e, LispContext ctx)
write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3); write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3);
lspShutdown(E.lsp_client); lspShutdown(E.lsp_client);
lisp_shutdown(E.ctx); lisp_shutdown(E.ctx);
deInitEditor(); // deInitEditor();
disableRawMode(); disableRawMode();
exit(0); exit(0);
} }
@@ -414,16 +417,23 @@ Lisp addPackage(Lisp args, LispError* e, LispContext ctx)
{ {
const char* package_name = lisp_string(lisp_car(args)); const char* package_name = lisp_string(lisp_car(args));
appDebug("%s\n", package_name); appDebug("%s\n", package_name);
char* package_dir = calloc(256, sizeof(char)); const char *home = getenv("HOME");
FILE* fd_package = NULL; if (!home) {
strcat(package_dir, getenv("HOME")); return lisp_null();
strcat(package_dir, "/.beluga/packages/"); }
strcat(package_dir, package_name);
strcat(package_dir, "/init.lisp"); char *package_dir;
appDebug("%s\n", package_dir); if (asprintf(&package_dir, "%s/.beluga/packages/%s/init.lisp", home, package_name) == -1) {
fd_package = fopen(package_dir, "r"); return lisp_null();
lisp_eval(lisp_read_file(fd_package, &E.ctx_error, E.ctx), &E.ctx_error, }
E.ctx);
FILE* fd_package = fopen(package_dir, "r");
if (!fd_package) {
free(package_dir);
return lisp_null();
}
lisp_eval(lisp_read_file(fd_package, &E.ctx_error, E.ctx), &E.ctx_error, E.ctx);
fclose(fd_package); fclose(fd_package);
free(package_dir); free(package_dir);
+14 -4
View File
@@ -49,13 +49,13 @@ int editorMoveCursor(int key) {
if (row && buf->x < row->size) { if (row && buf->x < row->size) {
int len = utf8Seqlen(row->chars[buf->x]); int len = utf8Seqlen(row->chars[buf->x]);
buf->x += len; buf->x += len;
} else if (row && buf->y < buf->numrows) { } else if (row && buf->y < buf->numrows - 1) {
buf->y++; buf->y++;
buf->x = 0; buf->x = 0;
} }
break; break;
case ARROW_DOWN: case ARROW_DOWN:
if (buf->y < buf->numrows) { if (buf->y < buf->numrows - 1) {
buf->y++; buf->y++;
} }
@@ -86,18 +86,28 @@ char *editorGetClipboard(void) {
size_t cap = 4096; size_t cap = 4096;
size_t len = 0; size_t len = 0;
char *buf = malloc(cap); char *buf = malloc(cap);
if (!buf) {
pclose(pipe);
return NULL;
}
int c; int c;
while ((c = fgetc(pipe)) != EOF) { while ((c = fgetc(pipe)) != EOF) {
if (len + 1 >= cap) { if (len + 1 >= cap) {
cap *= 2; cap *= 2;
buf = realloc(buf, cap); char *new_buf = realloc(buf, cap);
if (!new_buf) {
free(buf);
pclose(pipe);
return NULL;
}
buf = new_buf;
} }
buf[len++] = (char)c; buf[len++] = (char)c;
} }
buf[len] = '\0'; buf[len] = '\0';
pclose(pipe); pclose(pipe);
return buf; // caller must free return buf;
} }
void editorSetClipboard(const char *text, int len) { void editorSetClipboard(const char *text, int len) {
+4 -12
View File
@@ -60,19 +60,12 @@ void editorCloseFile(void) {
*/ */
void editorOpen(struct buffer_t* buffer) { void editorOpen(struct buffer_t* buffer) {
FILE *fp; FILE *fp;
char full_name[1024]; fp = fopen(buffer->fullname, "a+");
strcpy(full_name, buffer->path);
strcat(full_name, "/");
strcat(full_name, buffer->filename);
strcat(full_name, "\0");
appDebug("full name : %s", full_name);
fp = fopen(full_name, "a+");
if (!fp) if (!fp)
die("fopen"); die("fopen");
char *line = NULL; char *line = NULL;
size_t line_cap; size_t line_cap = 0;
ssize_t line_len; ssize_t line_len;
rewind(fp); rewind(fp);
@@ -82,12 +75,11 @@ void editorOpen(struct buffer_t* buffer) {
(line[line_len - 1] == '\n' || line[line_len - 1] == '\r')) { (line[line_len - 1] == '\n' || line[line_len - 1] == '\r')) {
--line_len; --line_len;
} }
appDebug("line %s\n", line);
bufferInsertRow(buffer, buffer->numrows, line, line_len); bufferInsertRow(buffer, buffer->numrows, line, line_len);
free(line); free(line);
line = NULL; line = NULL;
line_cap = 0; // Reset for next iteration
} }
free(line);
fclose(fp); fclose(fp);
E.dirty = 0; E.dirty = 0;
} }
@@ -114,7 +106,7 @@ void editorSave() {
return; return;
} }
} }
fd = open(buffer->fullname, O_RDWR | O_CREAT, 0644); fd = open(buffer->fullname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd != -1) { if (fd != -1) {
for (int i = 0; i < buffer->numrows; ++i) for (int i = 0; i < buffer->numrows; ++i)
{ {
+28 -8
View File
@@ -57,7 +57,7 @@ void initBuiltins() {
void initConfig() { void initConfig() {
E.ctx = lisp_init(); E.ctx = lisp_init();
E.ctx.p->err_port = fopen("log.err", "w"); E.ctx.p->err_port = fopen("lisp_log.err", "w");
E.env = lisp_env(E.ctx); E.env = lisp_env(E.ctx);
lisp_lib_load(E.ctx); lisp_lib_load(E.ctx);
// Init builtins lisp functions // Init builtins lisp functions
@@ -117,14 +117,26 @@ void initEditor() {
active->width = E.screencols; active->width = E.screencols;
active->height = E.screenrows; active->height = E.screenrows;
E.init_file_path = (char *)calloc(256, sizeof(char)); const char *home = getenv("HOME");
strcat(E.init_file_path, getenv("HOME")); if (!home) {
strcat(E.init_file_path, "/.beluga/config/init.lisp"); die("HOME environment variable not set");
appDebug("%s\n", E.init_file_path); }
E.fd_init_file = fopen(E.init_file_path, "r");
// Status bar if (asprintf(&E.init_file_path, "%s/.beluga/config/init.lisp", home) == -1) {
E.status_msg = (char *)calloc(E.screencols, sizeof(char)); die("asprintf failed");
}
E.fd_init_file = fopen(E.init_file_path, "r");
if (!E.fd_init_file) {
// File might not exist, that's okay for some cases
// Handle accordingly
}
E.status_msg = calloc(E.screencols, sizeof(char));
if (!E.status_msg) {
die("malloc failed");
}
E.status_msg[0] = '\0';
E.status_msg[0] = '\0'; E.status_msg[0] = '\0';
E.status_msg_time = 0; E.status_msg_time = 0;
@@ -168,5 +180,13 @@ void deInitEditor()
{ {
free(E.key_binds[i].key_sequence); free(E.key_binds[i].key_sequence);
} }
for (int i = 0; i < E.number_of_buffer; ++i)
{
free(E.buffers[i].filename);
free(E.buffers[i].path);
free(E.buffers[i].fullname);
free(E.buffers[i].row->chars);
free(E.buffers[i].row);
}
} }
+6 -3
View File
@@ -158,10 +158,13 @@ char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) {
} else if (!iscntrl(c) && c < 256) { } else if (!iscntrl(c) && c < 256) {
if (buf_len == buf_size - 1) { if (buf_len == buf_size - 1) {
buf_size *= 2; buf_size *= 2;
buf = realloc(buf, buf_size); char *new_buf = realloc(buf, buf_size);
if (!new_buf) {
free(buf);
return NULL;
}
buf = new_buf;
} }
buf[buf_len++] = (char)c;
buf[buf_len] = '\0';
} }
} }
} }
+10 -3
View File
@@ -20,7 +20,12 @@ void splitScreenInit(void) {
E.layout.num_panes = 1; E.layout.num_panes = 1;
E.layout.active_pane = 0; E.layout.active_pane = 0;
E.layout.panes = malloc(sizeof(EditorPane) * 2); EditorPane *new_panes = realloc(E.layout.panes, sizeof(EditorPane) * 2);
if (!new_panes) {
editorSetStatusMessage("Error: realloc failed");
return;
}
E.layout.panes = new_panes;
// Initialize single fullscreen pane // Initialize single fullscreen pane
E.layout.panes[0].buffer_id = -1; // No buffer for now E.layout.panes[0].buffer_id = -1; // No buffer for now
@@ -218,9 +223,11 @@ EditorPane *splitScreenGetActivePane(void) {
return &E.layout.panes[E.layout.active_pane]; return &E.layout.panes[E.layout.active_pane];
} }
void freeScreenLayout(ScreenLayout *layout) void freeScreenLayout(ScreenLayout *layout) {
{ if (layout) {
free(layout->panes); free(layout->panes);
layout->panes = NULL;
}
} }
void freePane(EditorPane *pane) void freePane(EditorPane *pane)
+20 -16
View File
@@ -110,9 +110,13 @@ int comment_section = 0;
char *highlight_line(const char *line, int *length) { char *highlight_line(const char *line, int *length) {
// Each byte can expand to at most (color_prefix + 4 bytes + color_reset). // Each byte can expand to at most (color_prefix + 4 bytes + color_reset).
// Allocate generously based on line length to avoid overflow. // Allocate generously based on line length to avoid overflow.
int line_len = strlen(line); int line_len = (int) strlen(line);
int buf_size = line_len * 32 + 256; int buf_size = line_len * 32 + 256;
char *result = malloc(buf_size); char *result = malloc(buf_size);
if (!result) {
*length = 0;
return NULL;
}
int result_pos = 0; int result_pos = 0;
int i = 0; int i = 0;
@@ -125,31 +129,31 @@ char *highlight_line(const char *line, int *length) {
} }
if (comment_section) { if (comment_section) {
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_COMMENT); result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_COMMENT);
while (line[i] != '\0' && line[i] != '\n') { while (line[i] != '\0' && line[i] != '\n') {
if (line[i] == '*' && line[i + 1] == '/') { if (line[i] == '*' && line[i + 1] == '/') {
comment_section = 0; comment_section = 0;
} }
copy_utf8_char(result, &result_pos, line, &i); copy_utf8_char(result, &result_pos, line, &i);
} }
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET); result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
continue; continue;
} }
// Handle line comments // Handle line comments
if (line[i] == '/' && line[i + 1] == '/') { if (line[i] == '/' && line[i + 1] == '/') {
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_COMMENT); result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_COMMENT);
while (line[i] != '\0' && line[i] != '\n') { while (line[i] != '\0' && line[i] != '\n') {
copy_utf8_char(result, &result_pos, line, &i); copy_utf8_char(result, &result_pos, line, &i);
} }
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET); result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
continue; continue;
} }
// Handle block comments // Handle block comments
if (line[i] == '/' && line[i + 1] == '*') { if (line[i] == '/' && line[i + 1] == '*') {
comment_section = 1; comment_section = 1;
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_COMMENT); result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_COMMENT);
result[result_pos++] = line[i++]; result[result_pos++] = line[i++];
result[result_pos++] = line[i++]; result[result_pos++] = line[i++];
while (line[i] != '\0') { while (line[i] != '\0') {
@@ -161,13 +165,13 @@ char *highlight_line(const char *line, int *length) {
} }
copy_utf8_char(result, &result_pos, line, &i); copy_utf8_char(result, &result_pos, line, &i);
} }
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET); result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
continue; continue;
} }
// Handle strings // Handle strings
if (line[i] == '"') { if (line[i] == '"') {
result_pos += sprintf(&result[result_pos], "%s\"", E.theme.COLOR_STRING); result_pos += snprintf(&result[result_pos], 10, "%s\"", E.theme.COLOR_STRING);
i++; i++;
while (line[i] != '\0' && line[i] != '"') { while (line[i] != '\0' && line[i] != '"') {
if (line[i] == '\\') { if (line[i] == '\\') {
@@ -179,13 +183,13 @@ char *highlight_line(const char *line, int *length) {
} }
if (line[i] == '"') if (line[i] == '"')
result[result_pos++] = line[i++]; result[result_pos++] = line[i++];
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET); result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
continue; continue;
} }
// Handle character literals // Handle character literals
if (line[i] == '\'') { if (line[i] == '\'') {
result_pos += sprintf(&result[result_pos], "%s'", E.theme.COLOR_STRING); result_pos += snprintf(&result[result_pos], 10, "%s'", E.theme.COLOR_STRING);
i++; i++;
while (line[i] != '\0' && line[i] != '\'') { while (line[i] != '\0' && line[i] != '\'') {
if (line[i] == '\\') { if (line[i] == '\\') {
@@ -197,17 +201,17 @@ char *highlight_line(const char *line, int *length) {
} }
if (line[i] == '\'') if (line[i] == '\'')
result[result_pos++] = line[i++]; result[result_pos++] = line[i++];
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET); result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
continue; continue;
} }
// Handle numbers // Handle numbers
if (line[i] >= '0' && line[i] <= '9') { if (line[i] >= '0' && line[i] <= '9') {
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_NUMBER); result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_NUMBER);
while (is_word_char(&line[i]) || line[i] == '.') { while (is_word_char(&line[i]) || line[i] == '.') {
copy_utf8_char(result, &result_pos, line, &i); copy_utf8_char(result, &result_pos, line, &i);
} }
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET); result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
continue; continue;
} }
@@ -231,15 +235,15 @@ char *highlight_line(const char *line, int *length) {
else if (is_type(word)) else if (is_type(word))
type = TOKEN_TYPE; type = TOKEN_TYPE;
result_pos += sprintf(&result[result_pos], "%s%s%s", get_color(type), result_pos += snprintf(&result[result_pos], 100, "%s%s%s", get_color(type),
word, COLOR_RESET); word, COLOR_RESET);
continue; continue;
} }
// Handle operators and other characters (including non-ASCII multi-byte) // Handle operators and other characters (including non-ASCII multi-byte)
result_pos += sprintf(&result[result_pos], "%s", E.theme.COLOR_DEFAULT); result_pos += snprintf(&result[result_pos], 10, "%s", E.theme.COLOR_DEFAULT);
copy_utf8_char(result, &result_pos, line, &i); copy_utf8_char(result, &result_pos, line, &i);
result_pos += sprintf(&result[result_pos], "%s", COLOR_RESET); result_pos += snprintf(&result[result_pos], 10, "%s", COLOR_RESET);
} }
result[result_pos] = '\0'; result[result_pos] = '\0';