Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2025-08-26 10:01:07 +01:00
3 changed files with 63 additions and 46 deletions

View File

@ -173,7 +173,7 @@ grid_view_delete_lines(struct grid *gd, u_int py, u_int ny, u_int bg)
sy = grid_view_y(gd, gd->sy); sy = grid_view_y(gd, gd->sy);
grid_move_lines(gd, py, py + ny, sy - py - ny, bg); grid_move_lines(gd, py, py + ny, sy - py - ny, bg);
grid_clear(gd, 0, sy - ny, gd->sx, py + ny - (sy - ny), bg); grid_clear(gd, 0, sy - ny, gd->sx, ny, bg);
} }
/* Delete lines inside scroll region. */ /* Delete lines inside scroll region. */
@ -221,7 +221,7 @@ grid_view_delete_cells(struct grid *gd, u_int px, u_int py, u_int nx, u_int bg)
sx = grid_view_x(gd, gd->sx); sx = grid_view_x(gd, gd->sx);
grid_move_cells(gd, px, px + nx, py, sx - px - nx, bg); grid_move_cells(gd, px, px + nx, py, sx - px - nx, bg);
grid_clear(gd, sx - nx, py, px + nx - (sx - nx), 1, bg); grid_clear(gd, sx - nx, py, nx, 1, bg);
} }
/* Convert cells into a string. */ /* Convert cells into a string. */

14
input.c
View File

@ -1234,7 +1234,7 @@ input_c0_dispatch(struct input_ctx *ictx)
struct window_pane *wp = ictx->wp; struct window_pane *wp = ictx->wp;
struct screen *s = sctx->s; struct screen *s = sctx->s;
struct grid_cell gc, first_gc; struct grid_cell gc, first_gc;
u_int cx = s->cx, line = s->cy + s->grid->hsize; u_int cx, line;
u_int width; u_int width;
int has_content = 0; int has_content = 0;
@ -1254,11 +1254,13 @@ input_c0_dispatch(struct input_ctx *ictx)
break; break;
case '\011': /* HT */ case '\011': /* HT */
/* Don't tab beyond the end of the line. */ /* Don't tab beyond the end of the line. */
if (s->cx >= screen_size_x(s) - 1) cx = s->cx;
if (cx >= screen_size_x(s) - 1)
break; break;
/* Find the next tab point, or use the last column if none. */ /* Find the next tab point, or use the last column if none. */
grid_get_cell(s->grid, s->cx, line, &first_gc); line = s->cy + s->grid->hsize;
grid_get_cell(s->grid, cx, line, &first_gc);
do { do {
if (!has_content) { if (!has_content) {
grid_get_cell(s->grid, cx, line, &gc); grid_get_cell(s->grid, cx, line, &gc);
@ -2701,7 +2703,7 @@ input_osc_8(struct input_ctx *ictx, const char *p)
struct hyperlinks *hl = ictx->ctx.s->hyperlinks; struct hyperlinks *hl = ictx->ctx.s->hyperlinks;
struct grid_cell *gc = &ictx->cell.cell; struct grid_cell *gc = &ictx->cell.cell;
const char *start, *end, *uri; const char *start, *end, *uri;
char *id = NULL; char *id = NULL;
for (start = p; (end = strpbrk(start, ":;")) != NULL; start = end + 1) { for (start = p; (end = strpbrk(start, ":;")) != NULL; start = end + 1) {
if (end - start >= 4 && strncmp(start, "id=", 3) == 0) { if (end - start >= 4 && strncmp(start, "id=", 3) == 0) {
@ -2896,8 +2898,8 @@ input_osc_52(struct input_ctx *ictx, const char *p)
int outlen, state; int outlen, state;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
struct paste_buffer *pb; struct paste_buffer *pb;
const char* allow = "cpqs01234567"; const char* allow = "cpqs01234567";
char flags[sizeof "cpqs01234567"] = ""; char flags[sizeof "cpqs01234567"] = "";
u_int i, j = 0; u_int i, j = 0;
if (wp == NULL) if (wp == NULL)

View File

@ -57,9 +57,9 @@ static void server_client_set_path(struct client *);
static void server_client_reset_state(struct client *); static void server_client_reset_state(struct client *);
static void server_client_update_latest(struct client *); static void server_client_update_latest(struct client *);
static void server_client_dispatch(struct imsg *, void *); static void server_client_dispatch(struct imsg *, void *);
static void server_client_dispatch_command(struct client *, struct imsg *); static int server_client_dispatch_command(struct client *, struct imsg *);
static void server_client_dispatch_identify(struct client *, struct imsg *); static int server_client_dispatch_identify(struct client *, struct imsg *);
static void server_client_dispatch_shell(struct client *); static int server_client_dispatch_shell(struct client *);
static void server_client_report_theme(struct client *, enum client_theme); static void server_client_report_theme(struct client *, enum client_theme);
/* Compare client windows. */ /* Compare client windows. */
@ -3339,14 +3339,16 @@ server_client_dispatch(struct imsg *imsg, void *arg)
case MSG_IDENTIFY_TERMINFO: case MSG_IDENTIFY_TERMINFO:
case MSG_IDENTIFY_TTYNAME: case MSG_IDENTIFY_TTYNAME:
case MSG_IDENTIFY_DONE: case MSG_IDENTIFY_DONE:
server_client_dispatch_identify(c, imsg); if (server_client_dispatch_identify(c, imsg) != 0)
goto bad;
break; break;
case MSG_COMMAND: case MSG_COMMAND:
server_client_dispatch_command(c, imsg); if (server_client_dispatch_command(c, imsg) != 0)
goto bad;
break; break;
case MSG_RESIZE: case MSG_RESIZE:
if (datalen != 0) if (datalen != 0)
fatalx("bad MSG_RESIZE size"); goto bad;
if (c->flags & CLIENT_CONTROL) if (c->flags & CLIENT_CONTROL)
break; break;
@ -3364,7 +3366,7 @@ server_client_dispatch(struct imsg *imsg, void *arg)
break; break;
case MSG_EXITING: case MSG_EXITING:
if (datalen != 0) if (datalen != 0)
fatalx("bad MSG_EXITING size"); goto bad;
server_client_set_session(c, NULL); server_client_set_session(c, NULL);
recalculate_sizes(); recalculate_sizes();
tty_close(&c->tty); tty_close(&c->tty);
@ -3373,7 +3375,7 @@ server_client_dispatch(struct imsg *imsg, void *arg)
case MSG_WAKEUP: case MSG_WAKEUP:
case MSG_UNLOCK: case MSG_UNLOCK:
if (datalen != 0) if (datalen != 0)
fatalx("bad MSG_WAKEUP size"); goto bad;
if (!(c->flags & CLIENT_SUSPENDED)) if (!(c->flags & CLIENT_SUSPENDED))
break; break;
@ -3395,9 +3397,9 @@ server_client_dispatch(struct imsg *imsg, void *arg)
break; break;
case MSG_SHELL: case MSG_SHELL:
if (datalen != 0) if (datalen != 0)
fatalx("bad MSG_SHELL size"); goto bad;
if (server_client_dispatch_shell(c) != 0)
server_client_dispatch_shell(c); goto bad;
break; break;
case MSG_WRITE_READY: case MSG_WRITE_READY:
file_write_ready(&c->files, imsg); file_write_ready(&c->files, imsg);
@ -3409,6 +3411,12 @@ server_client_dispatch(struct imsg *imsg, void *arg)
file_read_done(&c->files, imsg); file_read_done(&c->files, imsg);
break; break;
} }
return;
bad:
log_debug("client %p invalid message type %d", c, imsg->hdr.type);
proc_kill_peer(c->peer);
} }
/* Callback when command is not allowed. */ /* Callback when command is not allowed. */
@ -3436,7 +3444,7 @@ server_client_command_done(struct cmdq_item *item, __unused void *data)
} }
/* Handle command message. */ /* Handle command message. */
static void static int
server_client_dispatch_command(struct client *c, struct imsg *imsg) server_client_dispatch_command(struct client *c, struct imsg *imsg)
{ {
struct msg_command data; struct msg_command data;
@ -3450,16 +3458,16 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
if (c->flags & CLIENT_EXIT) if (c->flags & CLIENT_EXIT)
return; return (0);
if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data) if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data)
fatalx("bad MSG_COMMAND size"); return (-1);
memcpy(&data, imsg->data, sizeof data); memcpy(&data, imsg->data, sizeof data);
buf = (char *)imsg->data + sizeof data; buf = (char *)imsg->data + sizeof data;
len = imsg->hdr.len - IMSG_HEADER_SIZE - sizeof data; len = imsg->hdr.len - IMSG_HEADER_SIZE - sizeof data;
if (len > 0 && buf[len - 1] != '\0') if (len > 0 && buf[len - 1] != '\0')
fatalx("bad MSG_COMMAND string"); return (-1);
if (cmd_unpack_argv(buf, len, data.argc, &argv) != 0) { if (cmd_unpack_argv(buf, len, data.argc, &argv) != 0) {
cause = xstrdup("command too long"); cause = xstrdup("command too long");
@ -3495,7 +3503,7 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL)); cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL));
cmd_list_free(cmdlist); cmd_list_free(cmdlist);
return; return (0);
error: error:
cmd_free_argv(argc, argv); cmd_free_argv(argc, argv);
@ -3504,10 +3512,11 @@ error:
free(cause); free(cause);
c->flags |= CLIENT_EXIT; c->flags |= CLIENT_EXIT;
return (0);
} }
/* Handle identify message. */ /* Handle identify message. */
static void static int
server_client_dispatch_identify(struct client *c, struct imsg *imsg) server_client_dispatch_identify(struct client *c, struct imsg *imsg)
{ {
const char *data, *home; const char *data, *home;
@ -3517,7 +3526,7 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
char *name; char *name;
if (c->flags & CLIENT_IDENTIFIED) if (c->flags & CLIENT_IDENTIFIED)
fatalx("out-of-order identify message"); return (-1);
data = imsg->data; data = imsg->data;
datalen = imsg->hdr.len - IMSG_HEADER_SIZE; datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
@ -3525,7 +3534,7 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
switch (imsg->hdr.type) { switch (imsg->hdr.type) {
case MSG_IDENTIFY_FEATURES: case MSG_IDENTIFY_FEATURES:
if (datalen != sizeof feat) if (datalen != sizeof feat)
fatalx("bad MSG_IDENTIFY_FEATURES size"); return (-1);
memcpy(&feat, data, sizeof feat); memcpy(&feat, data, sizeof feat);
c->term_features |= feat; c->term_features |= feat;
log_debug("client %p IDENTIFY_FEATURES %s", c, log_debug("client %p IDENTIFY_FEATURES %s", c,
@ -3533,14 +3542,14 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
break; break;
case MSG_IDENTIFY_FLAGS: case MSG_IDENTIFY_FLAGS:
if (datalen != sizeof flags) if (datalen != sizeof flags)
fatalx("bad MSG_IDENTIFY_FLAGS size"); return (-1);
memcpy(&flags, data, sizeof flags); memcpy(&flags, data, sizeof flags);
c->flags |= flags; c->flags |= flags;
log_debug("client %p IDENTIFY_FLAGS %#x", c, flags); log_debug("client %p IDENTIFY_FLAGS %#x", c, flags);
break; break;
case MSG_IDENTIFY_LONGFLAGS: case MSG_IDENTIFY_LONGFLAGS:
if (datalen != sizeof longflags) if (datalen != sizeof longflags)
fatalx("bad MSG_IDENTIFY_LONGFLAGS size"); return (-1);
memcpy(&longflags, data, sizeof longflags); memcpy(&longflags, data, sizeof longflags);
c->flags |= longflags; c->flags |= longflags;
log_debug("client %p IDENTIFY_LONGFLAGS %#llx", c, log_debug("client %p IDENTIFY_LONGFLAGS %#llx", c,
@ -3548,16 +3557,13 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
break; break;
case MSG_IDENTIFY_TERM: case MSG_IDENTIFY_TERM:
if (datalen == 0 || data[datalen - 1] != '\0') if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_TERM string"); return (-1);
if (*data == '\0') c->term_name = xstrdup(data);
c->term_name = xstrdup("unknown");
else
c->term_name = xstrdup(data);
log_debug("client %p IDENTIFY_TERM %s", c, data); log_debug("client %p IDENTIFY_TERM %s", c, data);
break; break;
case MSG_IDENTIFY_TERMINFO: case MSG_IDENTIFY_TERMINFO:
if (datalen == 0 || data[datalen - 1] != '\0') if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_TERMINFO string"); return (-1);
c->term_caps = xreallocarray(c->term_caps, c->term_ncaps + 1, c->term_caps = xreallocarray(c->term_caps, c->term_ncaps + 1,
sizeof *c->term_caps); sizeof *c->term_caps);
c->term_caps[c->term_ncaps++] = xstrdup(data); c->term_caps[c->term_ncaps++] = xstrdup(data);
@ -3565,13 +3571,13 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
break; break;
case MSG_IDENTIFY_TTYNAME: case MSG_IDENTIFY_TTYNAME:
if (datalen == 0 || data[datalen - 1] != '\0') if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_TTYNAME string"); return (-1);
c->ttyname = xstrdup(data); c->ttyname = xstrdup(data);
log_debug("client %p IDENTIFY_TTYNAME %s", c, data); log_debug("client %p IDENTIFY_TTYNAME %s", c, data);
break; break;
case MSG_IDENTIFY_CWD: case MSG_IDENTIFY_CWD:
if (datalen == 0 || data[datalen - 1] != '\0') if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_CWD string"); return (-1);
if (access(data, X_OK) == 0) if (access(data, X_OK) == 0)
c->cwd = xstrdup(data); c->cwd = xstrdup(data);
else if ((home = find_home()) != NULL) else if ((home = find_home()) != NULL)
@ -3582,26 +3588,26 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
break; break;
case MSG_IDENTIFY_STDIN: case MSG_IDENTIFY_STDIN:
if (datalen != 0) if (datalen != 0)
fatalx("bad MSG_IDENTIFY_STDIN size"); return (-1);
c->fd = imsg_get_fd(imsg); c->fd = imsg_get_fd(imsg);
log_debug("client %p IDENTIFY_STDIN %d", c, c->fd); log_debug("client %p IDENTIFY_STDIN %d", c, c->fd);
break; break;
case MSG_IDENTIFY_STDOUT: case MSG_IDENTIFY_STDOUT:
if (datalen != 0) if (datalen != 0)
fatalx("bad MSG_IDENTIFY_STDOUT size"); return (-1);
c->out_fd = imsg_get_fd(imsg); c->out_fd = imsg_get_fd(imsg);
log_debug("client %p IDENTIFY_STDOUT %d", c, c->out_fd); log_debug("client %p IDENTIFY_STDOUT %d", c, c->out_fd);
break; break;
case MSG_IDENTIFY_ENVIRON: case MSG_IDENTIFY_ENVIRON:
if (datalen == 0 || data[datalen - 1] != '\0') if (datalen == 0 || data[datalen - 1] != '\0')
fatalx("bad MSG_IDENTIFY_ENVIRON string"); return (-1);
if (strchr(data, '=') != NULL) if (strchr(data, '=') != NULL)
environ_put(c->environ, data, 0); environ_put(c->environ, data, 0);
log_debug("client %p IDENTIFY_ENVIRON %s", c, data); log_debug("client %p IDENTIFY_ENVIRON %s", c, data);
break; break;
case MSG_IDENTIFY_CLIENTPID: case MSG_IDENTIFY_CLIENTPID:
if (datalen != sizeof c->pid) if (datalen != sizeof c->pid)
fatalx("bad MSG_IDENTIFY_CLIENTPID size"); return (-1);
memcpy(&c->pid, data, sizeof c->pid); memcpy(&c->pid, data, sizeof c->pid);
log_debug("client %p IDENTIFY_CLIENTPID %ld", c, (long)c->pid); log_debug("client %p IDENTIFY_CLIENTPID %ld", c, (long)c->pid);
break; break;
@ -3610,10 +3616,15 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
} }
if (imsg->hdr.type != MSG_IDENTIFY_DONE) if (imsg->hdr.type != MSG_IDENTIFY_DONE)
return; return (0);
c->flags |= CLIENT_IDENTIFIED; c->flags |= CLIENT_IDENTIFIED;
if (*c->ttyname != '\0') if (c->term_name == NULL || *c->term_name == '\0') {
free(c->term_name);
c->term_name = xstrdup("unknown");
}
if (c->ttyname == NULL || *c->ttyname != '\0')
name = xstrdup(c->ttyname); name = xstrdup(c->ttyname);
else else
xasprintf(&name, "client-%ld", (long)c->pid); xasprintf(&name, "client-%ld", (long)c->pid);
@ -3635,7 +3646,8 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
tty_resize(&c->tty); tty_resize(&c->tty);
c->flags |= CLIENT_TERMINAL; c->flags |= CLIENT_TERMINAL;
} }
close(c->out_fd); if (c->out_fd != -1)
close(c->out_fd);
c->out_fd = -1; c->out_fd = -1;
} }
@ -3648,10 +3660,12 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
!cfg_finished && !cfg_finished &&
c == TAILQ_FIRST(&clients)) c == TAILQ_FIRST(&clients))
start_cfg(); start_cfg();
return (0);
} }
/* Handle shell message. */ /* Handle shell message. */
static void static int
server_client_dispatch_shell(struct client *c) server_client_dispatch_shell(struct client *c)
{ {
const char *shell; const char *shell;
@ -3662,6 +3676,7 @@ server_client_dispatch_shell(struct client *c)
proc_send(c->peer, MSG_SHELL, -1, shell, strlen(shell) + 1); proc_send(c->peer, MSG_SHELL, -1, shell, strlen(shell) + 1);
proc_kill_peer(c->peer); proc_kill_peer(c->peer);
return (0);
} }
/* Get client working directory. */ /* Get client working directory. */