mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-22 14:39:24 -05:00
At last, a fix for `large-clipboard-crash'.
A growable buffer was only being grown for actual text, not for newlines or trailing NULs. A large run of empty lines could lead to newlines overflowing the buffer (> 100 should be enough to guarantee this on all platforms, after the initial 5k size of the buffer). Also fix some valgrind in the same area (was probably harmless), and a memory leak introduced by the RTF attribute pasting. [originally from svn r6570] [this svn revision also touched putty-wishlist]
This commit is contained in:
parent
9496269c6e
commit
9432d92b91
78
terminal.c
78
terminal.c
@ -5040,22 +5040,43 @@ void term_scroll(Terminal *term, int rel, int where)
|
|||||||
term_update(term);
|
term_update(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper routine for clipme(): growing buffer.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int buflen; /* amount of allocated space in textbuf/attrbuf */
|
||||||
|
int bufpos; /* amount of actual data */
|
||||||
|
wchar_t *textbuf; /* buffer for copied text */
|
||||||
|
wchar_t *textptr; /* = textbuf + bufpos (current insertion point) */
|
||||||
|
int *attrbuf; /* buffer for copied attributes */
|
||||||
|
int *attrptr; /* = attrbuf + bufpos */
|
||||||
|
} clip_workbuf;
|
||||||
|
|
||||||
|
static void clip_addchar(clip_workbuf *b, wchar_t chr, int attr)
|
||||||
|
{
|
||||||
|
if (b->bufpos >= b->buflen) {
|
||||||
|
b->buflen += 128;
|
||||||
|
b->textbuf = sresize(b->textbuf, b->buflen, wchar_t);
|
||||||
|
b->textptr = b->textbuf + b->bufpos;
|
||||||
|
b->attrbuf = sresize(b->attrbuf, b->buflen, int);
|
||||||
|
b->attrptr = b->attrbuf + b->bufpos;
|
||||||
|
}
|
||||||
|
*b->textptr++ = chr;
|
||||||
|
*b->attrptr++ = attr;
|
||||||
|
b->bufpos++;
|
||||||
|
}
|
||||||
|
|
||||||
static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
|
static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
|
||||||
{
|
{
|
||||||
wchar_t *workbuf;
|
clip_workbuf buf;
|
||||||
wchar_t *wbptr; /* where next char goes within workbuf */
|
|
||||||
int old_top_x;
|
int old_top_x;
|
||||||
int wblen = 0; /* workbuf len */
|
|
||||||
int buflen; /* amount of memory allocated to workbuf */
|
|
||||||
int *attrbuf; /* Attribute buffer */
|
|
||||||
int *attrptr;
|
|
||||||
int attr;
|
int attr;
|
||||||
|
|
||||||
buflen = 5120; /* Default size */
|
buf.buflen = 5120;
|
||||||
workbuf = snewn(buflen, wchar_t);
|
buf.bufpos = 0;
|
||||||
attrbuf = buflen ? snewn(buflen, int) : 0;
|
buf.textptr = buf.textbuf = snewn(buf.buflen, wchar_t);
|
||||||
wbptr = workbuf; /* start filling here */
|
buf.attrptr = buf.attrbuf = snewn(buf.buflen, int);
|
||||||
attrptr = attrbuf;
|
|
||||||
old_top_x = top.x; /* needed for rect==1 */
|
old_top_x = top.x; /* needed for rect==1 */
|
||||||
|
|
||||||
while (poslt(top, bottom)) {
|
while (poslt(top, bottom)) {
|
||||||
@ -5078,7 +5099,8 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
|
|||||||
* newline at the end)...
|
* newline at the end)...
|
||||||
*/
|
*/
|
||||||
if (!(ldata->lattr & LATTR_WRAPPED)) {
|
if (!(ldata->lattr & LATTR_WRAPPED)) {
|
||||||
while (IS_SPACE_CHR(ldata->chars[nlpos.x - 1].chr) &&
|
while (nlpos.x &&
|
||||||
|
IS_SPACE_CHR(ldata->chars[nlpos.x - 1].chr) &&
|
||||||
!ldata->chars[nlpos.x - 1].cc_next &&
|
!ldata->chars[nlpos.x - 1].cc_next &&
|
||||||
poslt(top, nlpos))
|
poslt(top, nlpos))
|
||||||
decpos(nlpos);
|
decpos(nlpos);
|
||||||
@ -5170,19 +5192,8 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (p = cbuf; *p; p++) {
|
for (p = cbuf; *p; p++)
|
||||||
/* Enough overhead for trailing NL and nul */
|
clip_addchar(&buf, *p, attr);
|
||||||
if (wblen >= buflen - 16) {
|
|
||||||
buflen += 100;
|
|
||||||
workbuf = sresize(workbuf, buflen, wchar_t);
|
|
||||||
wbptr = workbuf + wblen;
|
|
||||||
attrbuf = sresize(attrbuf, buflen, int);
|
|
||||||
attrptr = attrbuf + wblen;
|
|
||||||
}
|
|
||||||
wblen++;
|
|
||||||
*wbptr++ = *p;
|
|
||||||
*attrptr++ = attr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ldata->chars[x].cc_next)
|
if (ldata->chars[x].cc_next)
|
||||||
x += ldata->chars[x].cc_next;
|
x += ldata->chars[x].cc_next;
|
||||||
@ -5193,11 +5204,8 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
|
|||||||
}
|
}
|
||||||
if (nl) {
|
if (nl) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < sel_nl_sz; i++) {
|
for (i = 0; i < sel_nl_sz; i++)
|
||||||
wblen++;
|
clip_addchar(&buf, sel_nl[i], 0);
|
||||||
*wbptr++ = sel_nl[i];
|
|
||||||
*attrptr++ = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
top.y++;
|
top.y++;
|
||||||
top.x = rect ? old_top_x : 0;
|
top.x = rect ? old_top_x : 0;
|
||||||
@ -5205,12 +5213,12 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
|
|||||||
unlineptr(ldata);
|
unlineptr(ldata);
|
||||||
}
|
}
|
||||||
#if SELECTION_NUL_TERMINATED
|
#if SELECTION_NUL_TERMINATED
|
||||||
wblen++;
|
clip_addchar(&buf, 0, 0);
|
||||||
*wbptr++ = 0;
|
|
||||||
#endif
|
#endif
|
||||||
write_clip(term->frontend, workbuf, attrbuf, wblen, desel); /* transfer to clipbd */
|
/* Finally, transfer all that to the clipboard. */
|
||||||
if (buflen > 0) /* indicates we allocated this buffer */
|
write_clip(term->frontend, buf.textbuf, buf.attrbuf, buf.bufpos, desel);
|
||||||
sfree(workbuf);
|
sfree(buf.textbuf);
|
||||||
|
sfree(buf.attrbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void term_copyall(Terminal *term)
|
void term_copyall(Terminal *term)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user