]> git.pond.sub.org Git - empserver/commitdiff
(copy_ascii_no_funny, copy_utf8_no_funny)
authorMarkus Armbruster <armbru@pond.sub.org>
Mon, 13 Jun 2005 18:16:44 +0000 (18:16 +0000)
committerMarkus Armbruster <armbru@pond.sub.org>
Mon, 13 Jun 2005 18:16:44 +0000 (18:16 +0000)
(copy_utf8_to_ascii_no_funny): New.
(flash, wall, prmptrd, uprmptrd, getcommand): Use them to filter
input.
(uprnf, pr_flash): Use them to filter output.
(prtoascii): No longer used, remove.

(player_commands, player_commands_index): Internal linkage.

include/player.h
include/prototypes.h
src/lib/commands/flash.c
src/lib/player/empdis.c
src/lib/subs/pr.c

index 21c06d4918ffb8862729a0fb09e6b2f750fea920..dbf0904f2eb5d0bef045d2e3d848bc5a09a157ba 100644 (file)
@@ -57,7 +57,7 @@ struct player {
     int flags;
     struct cmndstr *command;
     struct iop *iop;
-    s_char combuf[1024];
+    char combuf[1024];         /* command input buffer, UTF-8 */
     s_char *argp[128];
     s_char *condarg;
     time_t lasttime;
index 837c6e3e47cb097e36c9f030d8bbc89935bd010d..91699e4b50f82c1d2ad7e0abd85bad3f391a0744 100644 (file)
@@ -418,7 +418,7 @@ extern void player_accept(void *);
 /* dispatch.c */
 extern int dispatch(char *, char *);
 /* empdis.c */
-extern int getcommand(s_char *);
+extern int getcommand(char *);
 extern void init_player_commands(void);
 extern void log_last_commands(void);
 extern int gamedown(void);
@@ -618,7 +618,9 @@ extern void PR(int, s_char *, ...) ATTRIBUTE((format (printf, 2, 3)));
 extern void PRdate(natid cn);
 extern void pr_beep(void);
 extern void mpr(int, s_char *, ...) ATTRIBUTE((format (printf, 2, 3)));
-extern void prtoascii(char *buf /* buf is message text */);
+extern size_t copy_ascii_no_funny(char *, char *);
+extern size_t copy_utf8_no_funny(char *, char *);
+extern size_t copy_utf8_to_ascii_no_funny(char *, char *);
 extern int ufindpfx(char *, int);
 
 /* radmap.c */
index 98c7e9f7901b70c8ee1ee201249016368c348885..f7f37eb4349b0d869c3d108db7ffaaa375f152c7 100644 (file)
@@ -44,9 +44,9 @@ flash(void)
 {
     struct natstr *us;
     struct natstr *to;
-    char buf[1024]; /* buf is message text */
+    char buf[1024];            /* UTF-8 */
     int tocn;
-    char *sp; /* sp is message text */
+    char *sp;                  /* points into player->combuf[], UTF-8 */
 
     us = getnatp(player->cnum);
     if ((tocn = natarg(player->argp[1], "to which country? ")) < 0)
@@ -76,14 +76,11 @@ flash(void)
     if (player->argp[2]) {
        for (sp = &player->combuf[0]; *sp && *sp != ' '; ++sp) ;
        for (++sp; *sp && *sp != ' '; ++sp) ;
-       sprintf(buf, ":%s", sp);
-       for(sp = buf; 0 != *sp; ++sp) {
-           if ((*sp >= 0x0 && *sp < 0x20  && *sp != '\t') ||
-               *sp == 0x7f)
-               *sp = '?';
-           else if (!(player->flags & PF_UTF8) && (*sp & 0x80))
-               *sp = '?';
-       }
+       buf[0] = ':';
+       if (player->flags & PF_UTF8)
+           strcpy(buf+1, sp);
+       else
+           copy_utf8_to_ascii_no_funny(buf+1, sp);
        sendmessage(us, to, buf, 1);
     } else {
        sendmessage(us, to, "...", 1);
@@ -101,20 +98,17 @@ int
 wall(void)
 {
     struct natstr *us;
-    char buf[1024]; /* buf is message text */
-    char *sp; /* sp is message text */
+    char buf[1024];            /* UTF-8 */
+    char *sp;                  /* points into player->combuf[], UTF-8 */
 
     us = getnatp(player->cnum);
     if (player->argp[1]) {
        for (sp = &player->combuf[0]; *sp && *sp != ' '; ++sp) ;
-       sprintf(buf, ":%s", sp);
-       for(sp = buf; 0 != *sp; ++sp) {
-           if ((*sp >= 0x0 && *sp < 0x20  && *sp != '\t') ||
-               *sp == 0x7f)
-               *sp = '?';
-           else if (!(player->flags & PF_UTF8) && (*sp & 0x80))
-               *sp = '?';
-       }
+       buf[0] = ':';
+       if (player->flags & PF_UTF8)
+           strcpy(buf+1, sp);
+       else
+           copy_utf8_to_ascii_no_funny(buf+1, sp);
        sendmessage(us, 0, buf, 1);
     } else {
        sendmessage(us, 0, "...", 1);
index 3d0f52153c25453e43102d5890c260b91d61c918..9ad05d6d4a2df6500ce27305e9686ac379b07718 100644 (file)
 #include <signal.h>
 
 #define KEEP_COMMANDS 50
-s_char player_commands[KEEP_COMMANDS][1024 + 8];
-int player_commands_index = 0;
 
+/* ring buffer of most recent command prompts and commands, user text */
+static char player_commands[KEEP_COMMANDS][1024 + 8];
+
+/* the slot holding the most recent command in player_commands[] */
+static int player_commands_index = 0;
+
+/*
+ * Get a command from the current player into COMBUFP[1024], in UTF-8.
+ * Return command's byte length on success, -1 on error.
+ */
 int
-getcommand(s_char *combufp)
+getcommand(char *combufp)
 {
-    struct natstr *natp;
-    s_char buf[1024];
+    struct natstr *natp = getnatp(player->cnum);
+    char buf[1024];            /* user text */
+    int i;
 
-/* Note this now assumes a 1024 byte buffer is being passed in */
-    natp = getnatp(player->cnum);
     if (++player_commands_index >= KEEP_COMMANDS)
        player_commands_index = 0;
     sprintf(player_commands[player_commands_index], "%3d %3d [prompt]",
            player_commands_index, player->cnum);
+
     do {
        prprompt(natp->nat_minused, natp->nat_btu);
        buf[0] = 0;
@@ -76,12 +84,15 @@ getcommand(s_char *combufp)
            return -1;
        }
     } while (buf[0] == 0);
+
     if (++player_commands_index >= KEEP_COMMANDS)
        player_commands_index = 0;
     sprintf(player_commands[player_commands_index], "%3d %3d %s",
            player_commands_index, player->cnum, buf);
-    strcpy(combufp, buf);
-    return (strlen(combufp));
+
+    if (player->flags & PF_UTF8)
+       return copy_utf8_no_funny(combufp, buf);
+    return copy_ascii_no_funny(combufp, buf);
 }
 
 void
index 45a29d545a576bca22b9bd1c1a19e782971a5e0d..86fd78755423d46ce7243b83ea56fa08f73b2ed9 100644 (file)
@@ -76,11 +76,8 @@ pr(char *format, ...)
 void
 uprnf(char *buf /* buf is message text */)
 {
-    /*
-     * Translate to ASCII if the client is not in UTF mode
-     */
     if (!(player->flags & PF_UTF8))
-       prtoascii(buf);
+       copy_utf8_to_ascii_no_funny(buf, buf);
 
     pr_player(player, C_DATA, buf);
 }
@@ -114,11 +111,8 @@ pr_flash(struct player *pl, char *format
     va_start(ap, format);
     (void)vsprintf(buf, format, ap);
     va_end(ap);
-    /*
-     * Translate to ASCII if the client is not in UTF mode
-     */
     if (!(pl->flags & PF_UTF8))
-       prtoascii(buf);
+       copy_utf8_to_ascii_no_funny(buf, buf);
     pr_player(pl, C_FLASH, buf);
     io_output(pl->iop, IO_NOWAIT);
 }
@@ -309,12 +303,9 @@ prmptrd(char *prompt, char *str, int size)
     time(&player->curup);
     if (*str == 0)
        return 1;
-    for(cp = str; 0 != *cp; ++cp) {
-       if ((*cp >= 0x0 && *cp < 0x20 && *cp != '\t') ||
-           *cp == 0x7f || *cp & 0x80)
-           *cp = '?';
-    }
-    return strlen(str);
+    if (player->flags & PF_UTF8)
+       return copy_utf8_to_ascii_no_funny(str, str);
+    return copy_ascii_no_funny(str, str);
 }
 
 int
@@ -329,15 +320,9 @@ uprmptrd(char *prompt, char *str /* str is message text */, int size)
     time(&player->curup);
     if (*str == 0)
        return 1;
-    
-    for(cp = str; 0 != *cp; ++cp) {
-       if ((*cp >= 0x0 && *cp < 0x20 && *cp != '\t') ||
-           *cp == 0x7f)
-           *cp = '?';
-       else if (!(player->flags & PF_UTF8) && (*cp & 0x80))
-           *cp = '?';
-    }
-    return strlen(str);
+    if (player->flags & PF_UTF8)
+       return copy_utf8_no_funny(str, str);
+    return copy_ascii_no_funny(str, str);
 }
 
 void
@@ -422,18 +407,89 @@ mpr(int cn, s_char *format, ...)
     }
 }
 
-void
-prtoascii(char *buf /* buf is message text */)
+/*
+ * Copy SRC without funny characters to DST.
+ * Drop control characters, except for '\t'.
+ * Replace non-ASCII characters by '?'.
+ * Return length of DST.
+ * DST must have space.  If it overlaps SRC, then DST <= SRC must
+ * hold.
+ */
+size_t
+copy_ascii_no_funny(char *dst, char *src)
 {
-    char *pbuf; /* pbuf is message text */
-
-    for(pbuf = buf; *pbuf != 0; pbuf++)
-       if ((*pbuf & 0xc0) == 0xc0)
-           *pbuf = '?';
-       else if (*pbuf & 0x80) {
-           memmove(pbuf,pbuf+1,strlen(pbuf)-1);
-           pbuf--;
-       }
+    char *p;
+    unsigned char ch;
+
+    p = dst;
+    while ((ch = *src++)) {
+       if ((ch < 0x20 && ch != '\t') || ch == 0x7f)
+           ;                   /* ignore control */
+       else if (ch > 0x7f)
+           *p++ = '?'; /* replace non-ASCII */
+       else
+           *p++ = ch;
+    }
+    *p = 0;
+
+    return p - dst;
+}
+
+/*
+ * Copy UTF-8 SRC without funny characters to DST.
+ * Drop control characters, except for '\t'.
+ * FIXME Replace malformed UTF-8 sequences by '?'.
+ * Return byte length of DST.
+ * DST must have space.  If it overlaps SRC, then DST <= SRC must
+ * hold.
+ */
+size_t
+copy_utf8_no_funny(char *dst, char *src)
+{
+    char *p;
+    unsigned char ch;
+
+    p = dst;
+    while ((ch = *src++)) {
+       /* FIXME do the right thing for malformed and overlong sequences */
+       if ((ch < 0x20 && ch != '\t') || ch == 0x7f)
+           ;                   /* ignore control */
+       else
+           *p++ = ch;
+    }
+    *p = 0;
+
+    return p - dst;
+}
+
+/*
+ * Copy UTF-8 SRC without funny characters to ASCII DST.
+ * Drop control characters, except for '\t'.
+ * Replace non-ASCII characters by '?'.
+ * Return length of DST.
+ * DST must have space.  If it overlaps SRC, then DST <= SRC must
+ * hold.
+ */
+size_t
+copy_utf8_to_ascii_no_funny(char *dst, char *src)
+{
+    char *p;
+    unsigned char ch;
+
+    p = dst;
+    while ((ch = *src++)) {
+       /* FIXME do the right thing for malformed and overlong sequences */
+       if ((ch < 0x20 && ch != '\t') || ch == 0x7f)
+           ;                   /* ignore control */
+       else if (ch > 0x7f) {
+           *p++ = '?';         /* replace non-ASCII */
+           while ((*src++ & 0xc0) == 0x80) ;
+       } else
+           *p++ = ch;
+    }
+    *p = 0;
+
+    return p - dst;
 }
 
 /*