diff --git a/main.c b/main.c index da862742..642bea23 100644 --- a/main.c +++ b/main.c @@ -818,6 +818,7 @@ out: if (term.kbd.xkb != NULL) xkb_context_unref(term.kbd.xkb); + free(term.vt.osc.data); for (int row = 0; row < term.normal.num_rows; row++) grid_row_free(term.normal.rows[row]); free(term.normal.rows); diff --git a/osc.c b/osc.c index 5697b230..21ee67c0 100644 --- a/osc.c +++ b/osc.c @@ -83,3 +83,23 @@ osc_dispatch(struct terminal *term) break; } } + +bool +osc_ensure_size(struct terminal *term, size_t required_size) +{ + if (required_size <= term->vt.osc.size) + return true; + + size_t new_size = (required_size + 127) / 128 * 128; + assert(new_size > 0); + + uint8_t *new_data = realloc(term->vt.osc.data, new_size); + if (new_data == NULL) { + LOG_ERRNO("failed to increase size of OSC buffer"); + return false; + } + + term->vt.osc.data = new_data; + term->vt.osc.size = new_size; + return true; +} diff --git a/osc.h b/osc.h index 9b0b8328..1a40116b 100644 --- a/osc.h +++ b/osc.h @@ -3,4 +3,5 @@ #include #include "terminal.h" +bool osc_ensure_size(struct terminal *term, size_t size); void osc_dispatch(struct terminal *term); diff --git a/terminal.h b/terminal.h index 8bfc3918..57e8c97a 100644 --- a/terminal.h +++ b/terminal.h @@ -125,7 +125,8 @@ struct vt { } params; char private; struct { - uint8_t data[1024]; + uint8_t *data; + size_t size; size_t idx; } osc; struct { diff --git a/vt.c b/vt.c index 3ce99250..8899fc74 100644 --- a/vt.c +++ b/vt.c @@ -909,12 +909,15 @@ action(struct terminal *term, enum action _action, uint8_t c) break; case ACTION_OSC_PUT: - if (term->vt.osc.idx < (int)sizeof(term->vt.osc.data) - 1) - term->vt.osc.data[term->vt.osc.idx++] = c; + if (!osc_ensure_size(term, term->vt.osc.idx + 1)) + break; + + term->vt.osc.data[term->vt.osc.idx++] = c; break; case ACTION_OSC_END: - assert(term->vt.osc.idx < sizeof(term->vt.osc.data)); + if (!osc_ensure_size(term, term->vt.osc.idx + 1)) + break; term->vt.osc.data[term->vt.osc.idx] = '\0'; osc_dispatch(term); break;