Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix the bug with input-line overrun from magic \%03o codes

Also fixes the \\\\\\\\\\\\\\\\\\\\\\ colour bug
  • Loading branch information...
commit 95ecd63986ca06b4a2125f35b6b698e991d701a5 1 parent 2027a5b
ec429 authored
View
7 Makefile
@@ -9,7 +9,7 @@ PREFIX := /usr/local
LIBS_ASYNCH_NL := -lanl
OPTLIBS = $(LIBS_ASYNCH_NL)
LIBS = -lm -lncurses $(OBJS) $(OPTLIBS)
-OBJS := ttyraw.o ttyesc.o irc.o bits.o strbuf.o colour.o buffer.o names.o config.o input.o logging.o types.o
+OBJS := ttyraw.o ttyesc.o irc.o bits.o strbuf.o ctbuf.o colour.o buffer.o names.o config.o input.o logging.o types.o
INCLUDE := $(OBJS:.o=.h) quirc.h version.h osconf.h
-include config.mak
@@ -69,9 +69,12 @@ bits.o: bits.c bits.h ttyesc.h colour.h
bits.h: config.h strbuf.h
touch bits.h
+ctbuf.h: colour.h
+ touch ctbuf.h
+
colour.o: colour.c colour.h c_init.c ttyesc.h
-buffer.o: buffer.c buffer.h ttyesc.h colour.h bits.h names.h text.h irc.h version.h input.h logging.h osconf.h
+buffer.o: buffer.c buffer.h ttyesc.h colour.h bits.h names.h text.h irc.h version.h input.h logging.h osconf.h ctbuf.h
buffer.h: config.h version.h logging.h
touch buffer.h
View
136 buffer.c
@@ -9,6 +9,9 @@
#include "buffer.h"
#include "logging.h"
#include "osconf.h"
+#include "ctbuf.h"
+
+ctchar *highlight(const char *src, size_t *len); // use colours to highlight \escapes. Returns a malloc-like pointer
int init_ring(ring *r)
{
@@ -738,86 +741,76 @@ void in_update(iline inp)
wwidth-=strlen(stamp);
}
// input
- if((unsigned)inp.left.i+(unsigned)inp.right.i+1<wwidth)
+ size_t ll, rl;
+ ctchar *left =highlight(inp.left .data?inp.left .data:"", &ll),
+ *right=highlight(inp.right.data?inp.right.data:"", &rl);
+ if(ll+rl+1<wwidth)
{
- char *lh=highlight(inp.left.data?inp.left.data:"");
- char *rh=highlight(inp.right.data?inp.right.data:"");
fputs(stamp, stdout);
- fputs(lh, stdout);
+ ct_puts(left);
savepos();
- fputs(rh, stdout);
+ ct_puts(right);
+ resetcol();
clr();
restpos();
- free(lh);
- free(rh);
}
else
{
- if(inp.left.i<wwidth*0.75)
+ if(ll<wwidth*0.75)
{
- char *lh=highlight(inp.left.data?inp.left.data:"");
- char rl[wwidth-inp.left.i-3-max(3, (wwidth-inp.left.i)/4)];
- snprintf(rl, wwidth-inp.left.i-3-max(3, (wwidth-inp.left.i)/4), "%s", inp.right.data);
- char *rlh=highlight(rl);
- char *rrh=highlight(inp.right.data+inp.right.i-max(3, (wwidth-inp.left.i)/4));
fputs(stamp, stdout);
- fputs(lh, stdout);
+ ct_puts(left);
savepos();
- printf("%s...%s", rlh, rrh);
+ ct_putsn(right, wwidth-ll-4-max(3, (wwidth-ll)/4));
+ resetcol();
+ fputs("...", stdout);
+ ct_puts(right+rl-max(3, (wwidth-ll)/4));
+ resetcol();
clr();
restpos();
- free(lh);
- free(rlh);
- free(rrh);
}
- else if(inp.right.i<wwidth*0.75)
+ else if(rl<wwidth*0.75)
{
- char ll[max(3, (wwidth-inp.right.i)/4)];
- snprintf(ll, max(3, (wwidth-inp.right.i)/4), "%s", inp.left.data);
- char *llh=highlight(ll);
- char *lrh=highlight(inp.left.data+inp.left.i-wwidth+3+inp.right.i+max(3, (wwidth-inp.right.i)/4));
- char *rh=highlight(inp.right.data?inp.right.data:"");
fputs(stamp, stdout);
- printf("%s...%s", llh, lrh);
+ ct_putsn(left, max(3, (wwidth-rl)/4));
+ resetcol();
+ fputs("...", stdout);
+ ct_puts(left+ll-wwidth+4+rl+max(3, (wwidth-rl)/4));
savepos();
- fputs(rh, stdout);
+ ct_puts(right);
+ resetcol();
+ clr();
restpos();
- free(llh);
- free(lrh);
- free(rh);
}
else
{
- int torem=floor((wwidth/4.0)*floor(((inp.left.i-(wwidth/2.0))*4.0/wwidth)+0.5));
- torem=min(torem, (int)inp.left.i-3);
- int c=inp.left.i+4-torem;
- char ll[max(3, c/4)+1];
- snprintf(ll, max(3, c/4)+1, "%s", inp.left.data);
- char *llh=highlight(ll);
- char *lrh=highlight(inp.left.data+torem+max(3, c/4));
- char rl[wwidth-c-2-max(3, (wwidth-c)/4)];
- snprintf(rl, wwidth-c-2-max(3, (wwidth-c)/4), "%s", inp.right.data);
- char *rlh=highlight(rl);
- char *rrh=highlight(inp.right.data+inp.right.i-max(3, (wwidth-c)/4));
+ int torem=floor((wwidth/4.0)*floor(((ll-(wwidth/2.0))*4.0/wwidth)+0.5));
+ torem=min(torem, (int)ll-3);
+ size_t c=ll+4-torem;
fputs(stamp, stdout);
- printf("%s...%s", llh, lrh);
+ ct_putsn(left, max(3, c/4)+1);
+ resetcol();
+ fputs("...", stdout);
+ ct_puts(left+torem+max(3, c/4)+1);
savepos();
- printf("%s...%s", rlh, rrh);
+ ct_putsn(right, wwidth-c-3-max(3, (wwidth-c)/4));
+ resetcol();
+ fputs("...", stdout);
+ ct_puts(right+rl-max(3, (wwidth-c)/4));
+ resetcol();
clr();
restpos();
- free(llh);
- free(lrh);
- free(rlh);
- free(rrh);
}
}
+ free(left);
+ free(right);
fflush(stdout);
}
-char *highlight(const char *src)
+ctchar *highlight(const char *src, size_t *len)
{
- size_t l,i;char *rv;
- init_char(&rv, &l, &i);
+ size_t l,i;ctchar *rv;
+ ct_init_char(&rv, &l, &i);
while(*src)
{
if(*src=='\\')
@@ -825,67 +818,52 @@ char *highlight(const char *src)
switch(src[1])
{
case 'n':
- s_setcol(7, 0, 1, 0, &rv, &l, &i);
- append_char(&rv, &l, &i, '\\');
- append_char(&rv, &l, &i, 'n');
- s_setcol(7, 0, 0, 0, &rv, &l, &i);
+ ct_append_char_c(&rv, &l, &i, (colour){7, 0, 1, 0}, '\\');
+ ct_append_char(&rv, &l, &i, 'n');
src++;
break;
case 'r':
- s_setcol(7, 0, 1, 0, &rv, &l, &i);
- append_char(&rv, &l, &i, '\\');
- append_char(&rv, &l, &i, 'r');
- s_setcol(7, 0, 0, 0, &rv, &l, &i);
+ ct_append_char_c(&rv, &l, &i, (colour){7, 0, 1, 0}, '\\');
+ ct_append_char(&rv, &l, &i, 'r');
src++;
break;
case '\\':
- s_setcol(3, 0, 1, 0, &rv, &l, &i);
- append_char(&rv, &l, &i, '\\');
- append_char(&rv, &l, &i, '\\');
- s_setcol(7, 0, 0, 0, &rv, &l, &i);
+ ct_append_char_c(&rv, &l, &i, (colour){3, 0, 1, 0}, '\\');
+ ct_append_char(&rv, &l, &i, '\\');
src++;
break;
case 0:
- s_setcol(4, 0, 1, 0, &rv, &l, &i);
- append_char(&rv, &l, &i, '\\');
- s_setcol(7, 0, 0, 0, &rv, &l, &i);
+ ct_append_char_c(&rv, &l, &i, (colour){4, 0, 1, 0}, '\\');
break;
case '0':
case '1':
case '2':
case '3':
- s_setcol(6, 0, 1, 0, &rv, &l, &i);
- append_char(&rv, &l, &i, '\\');
- append_char(&rv, &l, &i, *++src);
+ ct_append_char_c(&rv, &l, &i, (colour){6, 0, 1, 0}, '\\');
+ ct_append_char(&rv, &l, &i, *++src);
int digits=0;
while(isdigit(src[1])&&(src[1]<'8')&&(++digits<3))
- {
- append_char(&rv, &l, &i, *++src);
- }
- s_setcol(7, 0, 0, 0, &rv, &l, &i);
+ ct_append_char(&rv, &l, &i, *++src);
break;
default:
- s_setcol(1, 0, 1, 0, &rv, &l, &i);
- append_char(&rv, &l, &i, '\\');
- s_setcol(7, 0, 0, 0, &rv, &l, &i);
+ ct_append_char_c(&rv, &l, &i, (colour){1, 0, 1, 0}, '\\');
break;
}
}
else if(!isprint(*src))
{
- s_setcol(2, 0, 1, 1, &rv, &l, &i);
- append_char(&rv, &l, &i, '\\');
+ ct_append_char_c(&rv, &l, &i, (colour){2, 0, 1, 0}, '\\');
char obuf[16];
snprintf(obuf, 16, "%03o", (unsigned char)*src);
- append_str(&rv, &l, &i, obuf);
- s_setcol(7, 0, 0, 0, &rv, &l, &i);
+ ct_append_str(&rv, &l, &i, obuf);
}
else
{
- append_char(&rv, &l, &i, *src);
+ ct_append_char_c(&rv, &l, &i, (colour){7, 0, 1, 0}, *src);
}
src++;
}
+ if(len) *len=i;
return(rv);
}
View
1  buffer.h
@@ -114,7 +114,6 @@ int e_buf_print(int buf, mtype lm, message pkt, const char *lead);
int transfer_ring(ring *r, prio lq);
int push_ring(ring *r, prio lq);
void in_update(iline inp);
-char *highlight(const char *src); // use colours to highlight \escapes. Returns a malloc-like pointer
void titlebar(void);
int findptab(int b, const char *src);
int makeptab(int b, const char *src);
View
10 colour.c
@@ -7,6 +7,16 @@
*/
#include "colour.h"
+#include "ttyesc.h"
+
+inline bool eq_colour(colour a, colour b)
+{
+ if(a.fore!=b.fore) return(false);
+ if(a.back!=b.back) return(false);
+ if(a.hi!=b.hi) return(false);
+ if(a.ul!=b.ul) return(false);
+ return(true);
+}
int setcolour(colour c)
{
View
3  colour.h
@@ -19,8 +19,7 @@ typedef struct
}
colour;
-#include "ttyesc.h"
-
+bool eq_colour(colour, colour);
int setcolour(colour); // wrapper for setcol
int s_setcolour(colour, char **, size_t *, size_t *); // wrapper for s_setcol
colour c_mirc(int, int);
View
92 ctbuf.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "ctbuf.h"
+
+void ct_init_char(ctchar **buf, size_t *l, size_t *i)
+{
+ *l=80;
+ *buf=malloc(*l*sizeof(ctchar));
+ (*buf)[0].d=0;
+ *i=0;
+}
+
+void ct_append_char(ctchar **buf, size_t *l, size_t *i, char d)
+{
+ ct_append_char_c(buf, l, i, (*buf&&*i)?(*buf)[(*i)-1].c:(colour){.fore=7,.back=0,.hi=false,.ul=false}, d);
+}
+
+void ct_append_char_c(ctchar **buf, size_t *l, size_t *i, colour c, char d)
+{
+ if(*buf)
+ {
+ (*buf)[*i]=(ctchar){.c=c, .d=d};
+ (*i)++;
+ }
+ else
+ {
+ ct_init_char(buf, l, i);
+ ct_append_char_c(buf, l, i, c, d);
+ }
+ ctchar *nbuf=*buf;
+ if((*i)>=(*l))
+ {
+ *l=*i*2;
+ nbuf=realloc(*buf, *l*sizeof(ctchar));
+ }
+ if(nbuf)
+ {
+ *buf=nbuf;
+ (*buf)[*i].d=0;
+ }
+ else
+ {
+ free(*buf);
+ ct_init_char(buf, l, i);
+ }
+}
+
+void ct_append_str(ctchar **buf, size_t *l, size_t *i, const char *str)
+{
+ while(str && *str)
+ {
+ ct_append_char(buf, l, i, *str++);
+ }
+}
+
+void ct_append_str_c(ctchar **buf, size_t *l, size_t *i, colour c, const char *str)
+{
+ while(str && *str)
+ {
+ ct_append_char_c(buf, l, i, c, *str++);
+ }
+}
+
+void ct_putchar(ctchar a)
+{
+ setcolour(a.c);
+ putchar(a.d);
+}
+
+void ct_puts(const ctchar *buf)
+{
+ if(!buf) return;
+ size_t i=0;
+ while(buf[i].d)
+ {
+ if(!(i&&eq_colour(buf[i].c, buf[i-1].c)))
+ setcolour(buf[i].c);
+ putchar(buf[i++].d);
+ }
+}
+
+void ct_putsn(const ctchar *buf, size_t n)
+{
+ if(!buf) return;
+ size_t i=0;
+ while((buf[i].d)&&(i<n))
+ {
+ if(!(i&&eq_colour(buf[i].c, buf[i-1].c)))
+ setcolour(buf[i].c);
+ putchar(buf[i++].d);
+ }
+}
View
17 ctbuf.h
@@ -0,0 +1,17 @@
+#include "colour.h"
+
+typedef struct
+{
+ colour c;
+ char d;
+}
+ctchar;
+
+void ct_init_char(ctchar **buf, size_t *l, size_t *i);
+void ct_append_char(ctchar **buf, size_t *l, size_t *i, char d);
+void ct_append_char_c(ctchar **buf, size_t *l, size_t *i, colour c, char d);
+void ct_append_str(ctchar **buf, size_t *l, size_t *i, const char *str);
+void ct_append_str_c(ctchar **buf, size_t *l, size_t *i, colour c, const char *str);
+void ct_putchar(ctchar a);
+void ct_puts(const ctchar *buf);
+void ct_putsn(const ctchar *buf, size_t n);
View
2  plans
@@ -10,8 +10,6 @@ Handle \ in tab-completion. It should be expanded to \\.
Leave UTF8 alone when escaping unprintables in input buffer.
-Fix input-buffer-crush bug with magic \%03o codes.
-
Tab search, with ^T. Typing eg ^Tqu<return> should switch to the tab named quirc (assuming no other tabs have names containing "qu"). While entering the search string, all matching tabs should be highlighted on the strip.
Const-correctness. There are a lot of functions taking a char * that should take a const char *.
View
4 strbuf.c
@@ -24,7 +24,7 @@ void append_char(char **buf, size_t *l, size_t *i, char c)
if((*i)>=(*l))
{
*l=*i*2;
- nbuf=(char *)realloc(*buf, *l);
+ nbuf=realloc(*buf, *l);
}
if(nbuf)
{
@@ -49,7 +49,7 @@ void append_str(char **buf, size_t *l, size_t *i, const char *str)
void init_char(char **buf, size_t *l, size_t *i)
{
*l=80;
- *buf=(char *)malloc(*l);
+ *buf=malloc(*l);
(*buf)[0]=0;
*i=0;
}
View
2  strbuf.h
@@ -14,4 +14,4 @@ char *fgetl(FILE *); // gets a line of string data; returns a malloc-like pointe
char *slurp(FILE *); // gets an entire file of string data; returns a malloc-like pointer
void init_char(char **buf, size_t *l, size_t *i); // initialises a string buffer in heap. *buf becomes a malloc-like pointer
void append_char(char **buf, size_t *l, size_t *i, char c); // adds a character to a string buffer in heap (and realloc()s if needed)
-void append_str(char **buf, size_t*l, size_t *i, const char *str); // adds a string to a string buffer in heap (and realloc()s if needed)
+void append_str(char **buf, size_t *l, size_t *i, const char *str); // adds a string to a string buffer in heap (and realloc()s if needed)
View
9 wontfix
@@ -1,9 +0,0 @@
-==quIRC:bugs which WONTFIX or NOTABUG==
-
- * Pathological error in handling of escape sequence highlighting on cursor movement, input-line crushing etc. For instance
- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\003
- will sometimes show
- ...(yellow)\\\\(white)003
- instead of correct
- ...(yellow)\\\(cyan)\003
- This is essentially because the escape sequences are not self-synchronising in the case of \\. However, long strings of \\s are so unlikely that the considerable extra processing time /for all input editing/ required to fix is simply not worthwhile.
Please sign in to comment.
Something went wrong with that request. Please try again.