Commit 15094e4c authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

Merge branch 'memory-overallocation-fix'

parents e006b2ce 8bf8f645
......@@ -248,7 +248,8 @@ static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp,
int inchars_c = x_bufsize_c - inindex_c;
int maxindex_c =
(inchars_c > widthlimit_c ? widthlimit_c : inchars_c);
int maxindex_b = u8_offset(x->x_buf + inindex_b, maxindex_c);
int maxindex_b = u8_offset(x->x_buf + inindex_b, maxindex_c,
x->x_bufsize - inindex_b);
int eatchar = 1;
//fprintf(stderr, "firstone <%s> inindex_b=%d maxindex_b=%d\n", x->x_buf + inindex_b, inindex_b, maxindex_b);
int foundit_b = firstone(x->x_buf + inindex_b, '\n', maxindex_b);
......@@ -291,7 +292,8 @@ static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp,
{
int actualx = (findx < 0 ? 0 :
(findx > foundit_c ? foundit_c : findx));
*indexp = inindex_b + u8_offset(x->x_buf + inindex_b, actualx);
*indexp = inindex_b + u8_offset(x->x_buf + inindex_b, actualx,
x->x_bufsize - inindex_b);
reportedindex = 1;
}
strncpy(tempbuf+outchars_b, x->x_buf + inindex_b, foundit_b);
......@@ -557,6 +559,7 @@ void rtext_activate(t_rtext *x, int state)
{
//fprintf(stderr,"rtext_activate state=%d\n", state);
int w = 0, h = 0, widthspec, heightspec, indx, isgop;
char *tmpbuf;
t_glist *glist = x->x_glist;
t_canvas *canvas = glist_getcanvas(glist);
//if (state && x->x_active) printf("duplicate rtext_activate\n");
......@@ -610,6 +613,13 @@ void rtext_activate(t_rtext *x, int state)
/* we need to get scroll to make sure we've got the
correct bbox for the svg */
canvas_getscroll(glist_getcanvas(canvas));
/* ugly hack to get around the fact that x_buf is not
null terminated. If this becomes a problem we can revisit
it later */
tmpbuf = t_getbytes(x->x_bufsize + 1);
sprintf(tmpbuf, "%.*s", x->x_bufsize, x->x_buf);
/* in case x_bufsize is 0... */
tmpbuf[x->x_bufsize] = '\0';
gui_vmess("gui_textarea", "xssiiiisiii",
canvas,
x->x_tag,
......@@ -618,10 +628,11 @@ void rtext_activate(t_rtext *x, int state)
x->x_text->te_ypix,
widthspec,
heightspec,
x->x_buf,
tmpbuf,
sys_hostfontsize(glist_getfont(glist)),
isgop,
state);
freebytes(tmpbuf, x->x_bufsize + 1);
}
// outputs 1 if found one of the special chars
......
......@@ -3009,7 +3009,9 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos)
//any point of recreating the object
binbuf_gettext(x->te_binbuf, &c1, &i1);
binbuf_gettext(b, &c2, &i2);
if (strcmp(c1, c2))
/* must remember that binbuf_gettext does *not*
null-terminate, so we have to be careful here... */
if (i1 != i2 || strncmp(c1, c2, i1))
{
//fprintf(stderr,"string differs\n");
canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
......@@ -3063,7 +3065,7 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos)
more than just a series of nearly-incomprehensible
side-effects, perhaps the issue may be revisited.
*/
if (strcmp(c1, c2))
if (i1 != i2 || strncmp(c1, c2, i1))
{
//fprintf(stderr,"text_setto calls canvas_undo_add recreate\n");
canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
......@@ -3130,7 +3132,7 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos)
t_binbuf *b = binbuf_new();
binbuf_text(b, buf, bufsize);
binbuf_gettext(b, &c2, &i2);
if (!c1 || strcmp(c1, c2))
if (!c1 || i1 != i2 || strncmp(c1, c2, i1))
{
canvas_undo_add(glist_getcanvas(glist), 10, "typing",
(void *)canvas_undo_set_recreate(glist_getcanvas(glist),
......
......@@ -689,8 +689,8 @@ void binbuf_eval(t_binbuf *x, t_pd *target, int argc, t_atom *argv)
//first we need to check if the list of arguments has $@
//fprintf(stderr,"=========\nbinbuf_eval argc:%d ac:%d\n", argc, (int)ac);
int count;
for (count = 0; count < ac; count++)
int count, old_ac = ac;
for (count = 0; count < old_ac; count++)
{
//fprintf(stderr, "count %d\n", count);
if (at[count].a_type == A_DOLLAR &&
......
......@@ -22,7 +22,7 @@ void *getbytes(size_t nbytes)
void *ret;
if (nbytes < 1) nbytes = 1;
ret = (void *)calloc(nbytes, sizeof(char*));
ret = (void *)calloc(nbytes, 1);
#ifdef LOUD
fprintf(stderr, "new %lx %d\n", (int)ret, nbytes);
......@@ -55,9 +55,9 @@ void *resizebytes(void *old, size_t oldsize, size_t newsize)
void *ret;
if (newsize < 1) newsize = 1;
if (oldsize < 1) oldsize = 1;
ret = (void *)realloc((char *)old, newsize * sizeof(char*));
ret = (void *)realloc((char *)old, newsize);
if (newsize > oldsize && ret)
memset(((char *)ret) + oldsize, 0, (newsize - oldsize) * sizeof(char*));
memset(((char *)ret) + oldsize, 0, newsize - oldsize);
#ifdef LOUD
fprintf(stderr, "resize %lx %d --> %lx %d\n", (int)old, oldsize, (int)ret, newsize);
#endif /* LOUD */
......
......@@ -185,8 +185,27 @@ int u8_wc_toutf8_nul(char *dest, uint32_t ch)
}
/* charnum => byte offset */
int u8_offset(char *str, int charnum)
int u8_offset(char *str, int charnum, int bufsize)
{
/* Implementation #1 of a tricky encoding in an unsafe language. It
assumes that we're dealing with null-terminated strings, but
x_buf of rtext isn't null-terminated. */
/*
int offs=0;
while (charnum > 0 && str[offs]) {
(void)(isutf(str[++offs]) || isutf(str[++offs]) ||
isutf(str[++offs]) || ++offs);
charnum--;
}
return offs;
*/
/* Implementation number 2 apparently tried to fix that. Instead, it
just made a reimplementation that still potential dereferences
non-existent pointers _if_ we try to get the offset at the last
character _and_ that last character happens to be wide. */
/*
char *string = str;
while (charnum > 0 && *string != '\0') {
......@@ -205,11 +224,36 @@ int u8_offset(char *str, int charnum)
}
return (int)(string - str);
*/
/* Here is an _extremely_ conservative implementation that protects
against dereferencing garbage pointers. */
int offs = 0;
if (isutf(str[offs]))
{
for (offs = 0; offs < bufsize; offs++)
{
if (isutf(str[offs]))
{
if (charnum <= 0)
break;
charnum -= 1;
}
}
}
else
{
bug("u8_offset");
}
return offs;
}
/* byte offset => charnum */
int u8_charnum(char *s, int offset)
{
/* This has the same problem as the commented implementations of u8_offset
above. */
/*
int charnum = 0;
char *string = s;
char *const end = string + offset;
......@@ -229,6 +273,29 @@ int u8_charnum(char *s, int offset)
++charnum;
}
return charnum;
*/
/* The original implementation which doesn't work well with
strings that aren't null terminated */
/*
int charnum = 0, offs=0;
while (offs < offset && s[offs]) {
(void)(isutf(s[++offs]) || isutf(s[++offs]) ||
isutf(s[++offs]) || ++offs);
charnum++;
}
return charnum;
*/
/* An _extremely_ conservative implementation to avoid dereferencing
garbage. */
int charnum = 0, i;
for (i = 0; i < offset; i++)
{
if (isutf(s[i])) charnum += 1;
}
return charnum;
}
/* reads the next utf-8 sequence out of a string, updating an index */
......
......@@ -59,7 +59,7 @@ int u8_wc_toutf8(char *dest, uint32_t ch);
int u8_wc_toutf8_nul(char *dest, uint32_t ch);
/* character number to byte offset */
int u8_offset(char *str, int charnum);
int u8_offset(char *str, int charnum, int bufsize);
/* byte offset to character number */
int u8_charnum(char *s, int offset);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment