mirror of
https://github.com/tmate-io/tmate-ssh-server.git
synced 2020-11-18 19:53:51 -08:00
Lose intermediate handling (unused). Change argument parsing to work properly over multiple buffers by saving a copy of the argument (we can't just save off/len since the buffer may vanish at any point).
This commit is contained in:
parent
653ee721df
commit
1e316cfc7c
111
input.c
111
input.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: input.c,v 1.10 2007-09-29 10:57:39 nicm Exp $ */
|
/* $Id: input.c,v 1.11 2007-09-29 14:25:49 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -45,6 +45,8 @@ struct {
|
|||||||
|
|
||||||
enum input_class input_lookup_class(u_char);
|
enum input_class input_lookup_class(u_char);
|
||||||
int input_get_argument(struct input_ctx *, u_int, uint16_t *, uint16_t);
|
int input_get_argument(struct input_ctx *, u_int, uint16_t *, uint16_t);
|
||||||
|
int input_new_argument(struct input_ctx *);
|
||||||
|
int input_add_argument(struct input_ctx *, u_char ch);
|
||||||
|
|
||||||
void *input_state_first(u_char, enum input_class, struct input_ctx *);
|
void *input_state_first(u_char, enum input_class, struct input_ctx *);
|
||||||
void *input_state_escape(u_char, enum input_class, struct input_ctx *);
|
void *input_state_escape(u_char, enum input_class, struct input_ctx *);
|
||||||
@ -101,11 +103,39 @@ input_lookup_class(u_char ch)
|
|||||||
return (iclass);
|
return (iclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
input_new_argument(struct input_ctx *ictx)
|
||||||
|
{
|
||||||
|
struct input_arg *arg;
|
||||||
|
|
||||||
|
ARRAY_EXPAND(&ictx->args, 1);
|
||||||
|
|
||||||
|
arg = &ARRAY_LAST(&ictx->args);
|
||||||
|
arg->used = 0;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
input_add_argument(struct input_ctx *ictx, u_char ch)
|
||||||
|
{
|
||||||
|
struct input_arg *arg;
|
||||||
|
|
||||||
|
if (ARRAY_LENGTH(&ictx->args) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
arg = &ARRAY_LAST(&ictx->args);
|
||||||
|
if (arg->used > (sizeof arg->data) - 1)
|
||||||
|
return (-1);
|
||||||
|
arg->data[arg->used++] = ch;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
input_get_argument(struct input_ctx *ictx, u_int i, uint16_t *n, uint16_t d)
|
input_get_argument(struct input_ctx *ictx, u_int i, uint16_t *n, uint16_t d)
|
||||||
{
|
{
|
||||||
struct input_arg *arg;
|
struct input_arg *arg;
|
||||||
char tmp[64];
|
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
|
|
||||||
*n = d;
|
*n = d;
|
||||||
@ -113,15 +143,10 @@ input_get_argument(struct input_ctx *ictx, u_int i, uint16_t *n, uint16_t d)
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
arg = &ARRAY_ITEM(&ictx->args, i);
|
arg = &ARRAY_ITEM(&ictx->args, i);
|
||||||
if (arg->len == 0)
|
if (*arg->data == '\0')
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (arg->len > sizeof tmp - 1)
|
*n = strtonum(arg->data, 0, UINT16_MAX, &errstr);
|
||||||
return (-1);
|
|
||||||
memcpy(tmp, ictx->buf + arg->off, arg->len);
|
|
||||||
tmp[arg->len] = '\0';
|
|
||||||
|
|
||||||
*n = strtonum(tmp, 0, UINT16_MAX, &errstr);
|
|
||||||
if (errstr != NULL)
|
if (errstr != NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
return (0);
|
return (0);
|
||||||
@ -132,9 +157,6 @@ input_init(struct input_ctx *ictx, struct screen *s)
|
|||||||
{
|
{
|
||||||
ictx->s = s;
|
ictx->s = s;
|
||||||
|
|
||||||
ictx->intoff = 0;
|
|
||||||
ictx->intlen = 0;
|
|
||||||
|
|
||||||
ARRAY_INIT(&ictx->args);
|
ARRAY_INIT(&ictx->args);
|
||||||
|
|
||||||
ictx->state = input_state_first;
|
ictx->state = input_state_first;
|
||||||
@ -225,8 +247,6 @@ input_state_escape(u_char ch, enum input_class iclass, struct input_ctx *ictx)
|
|||||||
return (input_state_escape);
|
return (input_state_escape);
|
||||||
case INPUT_SPACE:
|
case INPUT_SPACE:
|
||||||
case INPUT_INTERMEDIATE:
|
case INPUT_INTERMEDIATE:
|
||||||
ictx->intoff = ictx->off;
|
|
||||||
ictx->intlen = 1;
|
|
||||||
return (input_state_intermediate);
|
return (input_state_intermediate);
|
||||||
case INPUT_PARAMETER:
|
case INPUT_PARAMETER:
|
||||||
input_handle_private_two(ch, ictx);
|
input_handle_private_two(ch, ictx);
|
||||||
@ -255,7 +275,6 @@ input_state_intermediate(
|
|||||||
switch (iclass) {
|
switch (iclass) {
|
||||||
case INPUT_SPACE:
|
case INPUT_SPACE:
|
||||||
case INPUT_INTERMEDIATE:
|
case INPUT_INTERMEDIATE:
|
||||||
ictx->intlen++;
|
|
||||||
return (input_state_intermediate);
|
return (input_state_intermediate);
|
||||||
case INPUT_PARAMETER:
|
case INPUT_PARAMETER:
|
||||||
input_handle_private_two(ch, ictx);
|
input_handle_private_two(ch, ictx);
|
||||||
@ -279,31 +298,30 @@ input_state_sequence_first(
|
|||||||
u_char ch, enum input_class iclass, struct input_ctx *ictx)
|
u_char ch, enum input_class iclass, struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
ictx->private = '\0';
|
ictx->private = '\0';
|
||||||
|
ARRAY_CLEAR(&ictx->args);
|
||||||
|
|
||||||
switch (iclass) {
|
switch (iclass) {
|
||||||
case INPUT_PARAMETER:
|
case INPUT_PARAMETER:
|
||||||
if (ch >= 0x3c && ch <= 0x3f) {
|
if (ch >= 0x3c && ch <= 0x3f) {
|
||||||
/* Private control sequence. */
|
/* Private control sequence. */
|
||||||
ictx->private = ch;
|
ictx->private = ch;
|
||||||
|
|
||||||
ictx->saved = ictx->off;
|
|
||||||
return (input_state_sequence_next);
|
return (input_state_sequence_next);
|
||||||
}
|
}
|
||||||
|
input_new_argument(ictx);
|
||||||
break;
|
break;
|
||||||
case INPUT_C0CONTROL:
|
|
||||||
case INPUT_C1CONTROL:
|
|
||||||
case INPUT_SPACE:
|
case INPUT_SPACE:
|
||||||
case INPUT_INTERMEDIATE:
|
case INPUT_INTERMEDIATE:
|
||||||
case INPUT_UPPERCASE:
|
case INPUT_UPPERCASE:
|
||||||
case INPUT_LOWERCASE:
|
case INPUT_LOWERCASE:
|
||||||
|
case INPUT_C0CONTROL:
|
||||||
|
case INPUT_C1CONTROL:
|
||||||
case INPUT_DELETE:
|
case INPUT_DELETE:
|
||||||
case INPUT_G1DISPLAYABLE:
|
case INPUT_G1DISPLAYABLE:
|
||||||
case INPUT_SPECIAL:
|
case INPUT_SPECIAL:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass this character to next state directly. */
|
/* Pass character on directly. */
|
||||||
ictx->saved = ictx->off - 1;
|
|
||||||
return (input_state_sequence_next(ch, iclass, ictx));
|
return (input_state_sequence_next(ch, iclass, ictx));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,39 +329,26 @@ void *
|
|||||||
input_state_sequence_next(
|
input_state_sequence_next(
|
||||||
u_char ch, enum input_class iclass, struct input_ctx *ictx)
|
u_char ch, enum input_class iclass, struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
struct input_arg *iarg;
|
|
||||||
|
|
||||||
switch (iclass) {
|
switch (iclass) {
|
||||||
case INPUT_SPACE:
|
case INPUT_SPACE:
|
||||||
case INPUT_INTERMEDIATE:
|
case INPUT_INTERMEDIATE:
|
||||||
if (ictx->saved != ictx->off) {
|
if (input_add_argument(ictx, '\0') != 0)
|
||||||
ARRAY_EXPAND(&ictx->args, 1);
|
break;
|
||||||
iarg = &ARRAY_LAST(&ictx->args);
|
|
||||||
iarg->off = ictx->saved;
|
|
||||||
iarg->len = ictx->off - ictx->saved - 1;
|
|
||||||
}
|
|
||||||
ictx->intoff = ictx->off;
|
|
||||||
ictx->intlen = 1;
|
|
||||||
return (input_state_sequence_intermediate);
|
return (input_state_sequence_intermediate);
|
||||||
case INPUT_PARAMETER:
|
case INPUT_PARAMETER:
|
||||||
if (ch == ';') {
|
if (ch == ';') {
|
||||||
ARRAY_EXPAND(&ictx->args, 1);
|
if (input_add_argument(ictx, '\0') != 0)
|
||||||
iarg = &ARRAY_LAST(&ictx->args);
|
break;
|
||||||
iarg->off = ictx->saved;
|
input_new_argument(ictx);
|
||||||
iarg->len = ictx->off - ictx->saved - 1;
|
|
||||||
|
|
||||||
ictx->saved = ictx->off;
|
|
||||||
return (input_state_sequence_next);
|
return (input_state_sequence_next);
|
||||||
}
|
}
|
||||||
|
if (input_add_argument(ictx, ch) != 0)
|
||||||
|
break;
|
||||||
return (input_state_sequence_next);
|
return (input_state_sequence_next);
|
||||||
case INPUT_UPPERCASE:
|
case INPUT_UPPERCASE:
|
||||||
case INPUT_LOWERCASE:
|
case INPUT_LOWERCASE:
|
||||||
if (ictx->saved != ictx->off) {
|
if (input_add_argument(ictx, '\0') != 0)
|
||||||
ARRAY_EXPAND(&ictx->args, 1);
|
break;
|
||||||
iarg = &ARRAY_LAST(&ictx->args);
|
|
||||||
iarg->off = ictx->saved;
|
|
||||||
iarg->len = ictx->off - ictx->saved - 1;
|
|
||||||
}
|
|
||||||
input_handle_sequence(ch, ictx);
|
input_handle_sequence(ch, ictx);
|
||||||
break;
|
break;
|
||||||
case INPUT_C0CONTROL:
|
case INPUT_C0CONTROL:
|
||||||
@ -363,7 +368,6 @@ input_state_sequence_intermediate(
|
|||||||
switch (iclass) {
|
switch (iclass) {
|
||||||
case INPUT_SPACE:
|
case INPUT_SPACE:
|
||||||
case INPUT_INTERMEDIATE:
|
case INPUT_INTERMEDIATE:
|
||||||
ictx->intlen++;
|
|
||||||
return (input_state_sequence_intermediate);
|
return (input_state_sequence_intermediate);
|
||||||
case INPUT_UPPERCASE:
|
case INPUT_UPPERCASE:
|
||||||
case INPUT_LOWERCASE:
|
case INPUT_LOWERCASE:
|
||||||
@ -437,8 +441,7 @@ input_handle_c1_control(u_char ch, struct input_ctx *ictx)
|
|||||||
void
|
void
|
||||||
input_handle_private_two(u_char ch, struct input_ctx *ictx)
|
input_handle_private_two(u_char ch, struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
log_debug2("-- p2 %zu: %hhu (%c) (%zu, %zu)",
|
log_debug2("-- p2 %zu: %hhu (%c)", ictx->off, ch, ch);
|
||||||
ictx->off, ch, ch, ictx->intoff, ictx->intlen);
|
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '=': /* DECKPAM */
|
case '=': /* DECKPAM */
|
||||||
@ -456,8 +459,7 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
|
|||||||
void
|
void
|
||||||
input_handle_standard_two(u_char ch, struct input_ctx *ictx)
|
input_handle_standard_two(u_char ch, struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
log_debug2("-- s2 %zu: %hhu (%c) (%zu,%zu)",
|
log_debug2("-- s2 %zu: %hhu (%c)", ictx->off, ch, ch);
|
||||||
ictx->off, ch, ch, ictx->intoff, ictx->intlen);
|
|
||||||
|
|
||||||
log_debug("unknown s2: %hhu", ch);
|
log_debug("unknown s2: %hhu", ch);
|
||||||
}
|
}
|
||||||
@ -491,26 +493,21 @@ input_handle_sequence(u_char ch, struct input_ctx *ictx)
|
|||||||
u_int i;
|
u_int i;
|
||||||
struct input_arg *iarg;
|
struct input_arg *iarg;
|
||||||
|
|
||||||
log_debug2("-- sq %zu: %hhu (%c) (%zu,%zu): %u",
|
log_debug2("-- sq "
|
||||||
ictx->off, ch, ch, ictx->intoff, ictx->intlen,
|
"%zu: %hhu (%c): %u", ictx->off, ch, ch, ARRAY_LENGTH(&ictx->args));
|
||||||
ARRAY_LENGTH(&ictx->args));
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&ictx->args); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&ictx->args); i++) {
|
||||||
iarg = &ARRAY_ITEM(&ictx->args, i);
|
iarg = &ARRAY_ITEM(&ictx->args, i);
|
||||||
if (iarg->len > 0) {
|
if (*iarg->data != '\0')
|
||||||
log_debug2(" ++ %u: (%zu) %.*s", i,
|
log_debug2(" ++ %u: %s", i, iarg->data);
|
||||||
iarg->len, (int) iarg->len, ictx->buf + iarg->off);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX bsearch? */
|
/* XXX bsearch? */
|
||||||
for (i = 0; i < (sizeof table / sizeof table[0]); i++) {
|
for (i = 0; i < (sizeof table / sizeof table[0]); i++) {
|
||||||
if (table[i].ch == ch) {
|
if (table[i].ch == ch) {
|
||||||
table[i].fn(ictx);
|
table[i].fn(ictx);
|
||||||
ARRAY_CLEAR(&ictx->args);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ARRAY_CLEAR(&ictx->args);
|
|
||||||
|
|
||||||
log_debug("unknown sq: %c (%hhu %hhu)", ch, ch, ictx->private);
|
log_debug("unknown sq: %c (%hhu %hhu)", ch, ch, ictx->private);
|
||||||
}
|
}
|
||||||
|
4
local.c
4
local.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: local.c,v 1.10 2007-09-29 10:57:39 nicm Exp $ */
|
/* $Id: local.c,v 1.11 2007-09-29 14:25:49 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -310,11 +310,13 @@ local_putc(int c)
|
|||||||
if (c < 0 || c > (int) UCHAR_MAX)
|
if (c < 0 || c > (int) UCHAR_MAX)
|
||||||
fatalx("invalid character");
|
fatalx("invalid character");
|
||||||
|
|
||||||
|
/* XXX
|
||||||
if (debug_level > 2) {
|
if (debug_level > 2) {
|
||||||
f = fopen("tmux-out.log", "a+");
|
f = fopen("tmux-out.log", "a+");
|
||||||
fprintf(f, "%c", ch);
|
fprintf(f, "%c", ch);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
buffer_write(local_out, &ch, 1);
|
buffer_write(local_out, &ch, 1);
|
||||||
return (c);
|
return (c);
|
||||||
|
11
tmux.h
11
tmux.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tmux.h,v 1.25 2007-09-29 13:22:15 nicm Exp $ */
|
/* $Id: tmux.h,v 1.26 2007-09-29 14:25:49 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -399,8 +399,8 @@ struct screen {
|
|||||||
|
|
||||||
/* Input parser sequence argument. */
|
/* Input parser sequence argument. */
|
||||||
struct input_arg {
|
struct input_arg {
|
||||||
size_t off;
|
u_char data[64];
|
||||||
size_t len;
|
size_t used;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Input character classes. */
|
/* Input character classes. */
|
||||||
@ -431,10 +431,6 @@ struct input_ctx {
|
|||||||
|
|
||||||
void *(*state)(u_char, enum input_class, struct input_ctx *);
|
void *(*state)(u_char, enum input_class, struct input_ctx *);
|
||||||
|
|
||||||
size_t intoff;
|
|
||||||
size_t intlen;
|
|
||||||
|
|
||||||
size_t saved;
|
|
||||||
u_char private;
|
u_char private;
|
||||||
ARRAY_DECL(, struct input_arg) args;
|
ARRAY_DECL(, struct input_arg) args;
|
||||||
};
|
};
|
||||||
@ -663,6 +659,7 @@ __dead void log_fatalx(const char *, ...);
|
|||||||
/* xmalloc.c */
|
/* xmalloc.c */
|
||||||
void *ensure_size(void *, size_t *, size_t, size_t);
|
void *ensure_size(void *, size_t *, size_t, size_t);
|
||||||
void *ensure_for(void *, size_t *, size_t, size_t);
|
void *ensure_for(void *, size_t *, size_t, size_t);
|
||||||
|
char *xmemstrdup(const char *, size_t);
|
||||||
char *xstrdup(const char *);
|
char *xstrdup(const char *);
|
||||||
void *xcalloc(size_t, size_t);
|
void *xcalloc(size_t, size_t);
|
||||||
void *xmalloc(size_t);
|
void *xmalloc(size_t);
|
||||||
|
10
window.c
10
window.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: window.c,v 1.13 2007-09-29 09:15:49 nicm Exp $ */
|
/* $Id: window.c,v 1.14 2007-09-29 14:25:49 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -314,9 +314,17 @@ window_input(struct window *w, struct buffer *b, size_t size)
|
|||||||
void
|
void
|
||||||
window_output(struct window *w, struct buffer *b)
|
window_output(struct window *w, struct buffer *b)
|
||||||
{
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
if (BUFFER_USED(w->in) == 0)
|
if (BUFFER_USED(w->in) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (debug_level > 2) {
|
||||||
|
f = fopen("tmux-in.log", "a+");
|
||||||
|
fwrite(BUFFER_OUT(w->in), BUFFER_USED(w->in), 1, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
input_parse(&w->ictx, BUFFER_OUT(w->in), BUFFER_USED(w->in), b);
|
input_parse(&w->ictx, BUFFER_OUT(w->in), BUFFER_USED(w->in), b);
|
||||||
buffer_remove(w->in, BUFFER_USED(w->in));
|
buffer_remove(w->in, BUFFER_USED(w->in));
|
||||||
|
|
||||||
|
14
xmalloc.c
14
xmalloc.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: xmalloc.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
|
/* $Id: xmalloc.c,v 1.3 2007-09-29 14:25:49 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2004 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -69,6 +69,18 @@ ensure_size(void *buf, size_t *len, size_t nmemb, size_t size)
|
|||||||
return (buf);
|
return (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
xmemstrdup(const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
s = xmalloc(len + 1);
|
||||||
|
memcpy(s, buf, len);
|
||||||
|
s[len] = '\0';
|
||||||
|
|
||||||
|
return (s);
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
xstrdup(const char *s)
|
xstrdup(const char *s)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user