devdraw, acme, snarfer: remove 64KB snarf buffer limit
The snarf code silently dropped text larger than SnarfSize (64KB), causing paste to produce nothing. Replace the static clip buffer with a dynamically allocated one, remove all the size checks, and read the actual X11 property size instead of capping at SnarfSize.
This commit is contained in:
committed by
Dan Cross
parent
ae4fdf4268
commit
0d87d4b75e
@@ -547,10 +547,6 @@ extern void drawsetdebug(int);
|
||||
/*
|
||||
* Snarf buffer
|
||||
*/
|
||||
enum
|
||||
{
|
||||
SnarfSize = 64*1024
|
||||
};
|
||||
char *getsnarf(void);
|
||||
void putsnarf(char*);
|
||||
|
||||
|
||||
@@ -1090,11 +1090,6 @@ iconinit(void)
|
||||
* fd here rather than use snarffd
|
||||
*/
|
||||
|
||||
/* rio truncates larges snarf buffers, so this avoids using the
|
||||
* service if the string is huge */
|
||||
|
||||
#define MAXSNARF 100*1024
|
||||
|
||||
void
|
||||
acmeputsnarf(void)
|
||||
{
|
||||
@@ -1104,8 +1099,6 @@ acmeputsnarf(void)
|
||||
|
||||
if(snarfbuf.nc==0)
|
||||
return;
|
||||
if(snarfbuf.nc > MAXSNARF)
|
||||
return;
|
||||
|
||||
fmtstrinit(&f);
|
||||
for(i=0; i<snarfbuf.nc; i+=n){
|
||||
|
||||
@@ -1109,7 +1109,7 @@ rpc_getsnarf(void)
|
||||
void
|
||||
rpc_putsnarf(char *s)
|
||||
{
|
||||
if(s == nil || strlen(s) >= SnarfSize)
|
||||
if(s == nil)
|
||||
return;
|
||||
|
||||
dispatch_sync(dispatch_get_main_queue(), ^(void) {
|
||||
|
||||
@@ -1454,9 +1454,8 @@ rpc_setcursor(Client *client, Cursor *c, Cursor2 *c2)
|
||||
|
||||
struct {
|
||||
QLock lk;
|
||||
char buf[SnarfSize];
|
||||
char *buf;
|
||||
#ifdef APPLESNARF
|
||||
Rune rbuf[SnarfSize];
|
||||
PasteboardRef apple;
|
||||
#endif
|
||||
} clip;
|
||||
@@ -1498,7 +1497,7 @@ _xgetsnarffrom(Xwin *w, XWindow xw, Atom clipboard, Atom target, int timeout0, i
|
||||
|
||||
/* get the property */
|
||||
xdata = nil;
|
||||
XGetWindowProperty(_x.display, w->drawable, prop, 0, SnarfSize/sizeof(ulong), 0,
|
||||
XGetWindowProperty(_x.display, w->drawable, prop, 0, (len+3)/4, 0,
|
||||
AnyPropertyType, &type, &fmt, &len, &dummy, &xdata);
|
||||
if((type != target && type != XA_STRING && type != _x.utf8string) || len == 0){
|
||||
if(xdata)
|
||||
@@ -1538,7 +1537,9 @@ rpc_getsnarf(void)
|
||||
// TODO check more
|
||||
if(xw == w->drawable){
|
||||
mine:
|
||||
data = (uchar*)strdup(clip.buf);
|
||||
data = nil;
|
||||
if(clip.buf != nil)
|
||||
data = (uchar*)strdup(clip.buf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1577,12 +1578,11 @@ __xputsnarf(char *data)
|
||||
XButtonEvent e;
|
||||
Xwin *w;
|
||||
|
||||
if(strlen(data) >= SnarfSize)
|
||||
return;
|
||||
qlock(&clip.lk);
|
||||
xlock();
|
||||
w = _x.windows;
|
||||
strcpy(clip.buf, data);
|
||||
free(clip.buf);
|
||||
clip.buf = strdup(data);
|
||||
/* leave note for mouse proc to assert selection ownership */
|
||||
_x.putsnarf++;
|
||||
|
||||
@@ -1627,8 +1627,12 @@ if(0) fprint(2, "xselect target=%d requestor=%d property=%d selection=%d (sizeof
|
||||
/* text/plain;charset=utf-8 is used by xfce4-terminal 1.0.4 */
|
||||
/* if the target is STRING we're supposed to reply with Latin1 XXX */
|
||||
qlock(&clip.lk);
|
||||
XChangeProperty(_x.display, xe->requestor, xe->property, xe->target,
|
||||
8, PropModeReplace, (uchar*)clip.buf, strlen(clip.buf));
|
||||
if(clip.buf)
|
||||
XChangeProperty(_x.display, xe->requestor, xe->property, xe->target,
|
||||
8, PropModeReplace, (uchar*)clip.buf, strlen(clip.buf));
|
||||
else
|
||||
XChangeProperty(_x.display, xe->requestor, xe->property, xe->target,
|
||||
8, PropModeReplace, (uchar*)"", 0);
|
||||
qunlock(&clip.lk);
|
||||
}else{
|
||||
if(strcmp(name, "TIMESTAMP") != 0)
|
||||
@@ -1674,7 +1678,9 @@ _applegetsnarf(void)
|
||||
}
|
||||
flags = PasteboardSynchronize(clip.apple);
|
||||
if(flags&kPasteboardClientIsOwner){
|
||||
s = strdup(clip.buf);
|
||||
s = nil;
|
||||
if(clip.buf != nil)
|
||||
s = strdup(clip.buf);
|
||||
qunlock(&clip.lk);
|
||||
return s;
|
||||
}
|
||||
@@ -1716,14 +1722,21 @@ _appleputsnarf(char *s)
|
||||
{
|
||||
CFDataRef cfdata;
|
||||
PasteboardSyncFlags flags;
|
||||
Rune *r;
|
||||
int n;
|
||||
|
||||
/* fprint(2, "appleputsnarf\n"); */
|
||||
|
||||
if(strlen(s) >= SnarfSize)
|
||||
return;
|
||||
qlock(&clip.lk);
|
||||
strcpy(clip.buf, s);
|
||||
runesnprint(clip.rbuf, nelem(clip.rbuf), "%s", s);
|
||||
free(clip.buf);
|
||||
clip.buf = strdup(s);
|
||||
n = utflen(s) + 1;
|
||||
r = malloc(n * sizeof(Rune));
|
||||
if(r == nil){
|
||||
qunlock(&clip.lk);
|
||||
return;
|
||||
}
|
||||
runesnprint(r, n, "%s", s);
|
||||
if(clip.apple == nil){
|
||||
if(PasteboardCreate(kPasteboardClipboard, &clip.apple) != noErr){
|
||||
fprint(2, "apple pasteboard create failed\n");
|
||||
@@ -1733,17 +1746,20 @@ _appleputsnarf(char *s)
|
||||
}
|
||||
if(PasteboardClear(clip.apple) != noErr){
|
||||
fprint(2, "apple pasteboard clear failed\n");
|
||||
free(r);
|
||||
qunlock(&clip.lk);
|
||||
return;
|
||||
}
|
||||
flags = PasteboardSynchronize(clip.apple);
|
||||
if((flags&kPasteboardModified) || !(flags&kPasteboardClientIsOwner)){
|
||||
fprint(2, "apple pasteboard cannot assert ownership\n");
|
||||
free(r);
|
||||
qunlock(&clip.lk);
|
||||
return;
|
||||
}
|
||||
cfdata = CFDataCreate(kCFAllocatorDefault,
|
||||
(uchar*)clip.rbuf, runestrlen(clip.rbuf)*2);
|
||||
(uchar*)r, runestrlen(r)*2);
|
||||
free(r);
|
||||
if(cfdata == nil){
|
||||
fprint(2, "apple pasteboard cfdatacreate failed\n");
|
||||
qunlock(&clip.lk);
|
||||
|
||||
@@ -54,11 +54,8 @@ AUTOFRAMEWORK(Carbon)
|
||||
#undef time
|
||||
AUTOLIB(draw) /* to cause link of X11 */
|
||||
|
||||
enum {
|
||||
SnarfSize = 65536
|
||||
};
|
||||
char snarf[3*SnarfSize+1];
|
||||
Rune rsnarf[SnarfSize+1];
|
||||
char *snarf;
|
||||
Rune *rsnarf;
|
||||
XDisplay *xdisplay;
|
||||
XWindow drawable;
|
||||
Atom xclipboard;
|
||||
@@ -98,6 +95,7 @@ main(int argc, char **argv)
|
||||
break;
|
||||
}ARGEND
|
||||
|
||||
snarf = strdup("");
|
||||
if((xdisplay = XOpenDisplay(nil)) == nil)
|
||||
sysfatal("XOpenDisplay: %r");
|
||||
drawable = XCreateWindow(xdisplay, DefaultRootWindow(xdisplay),
|
||||
@@ -256,18 +254,16 @@ xgetsnarf(void)
|
||||
return nil;
|
||||
/* get the property */
|
||||
data = nil;
|
||||
XGetWindowProperty(xd, drawable, prop, 0, SnarfSize/sizeof(ulong), 0,
|
||||
XGetWindowProperty(xd, drawable, prop, 0, (len+3)/4, 0,
|
||||
AnyPropertyType, &type, &fmt, &len, &dummy, &xdata);
|
||||
if(xdata == nil || (type != XA_STRING && type != xutf8string) || len == 0){
|
||||
if(xdata)
|
||||
XFree(xdata);
|
||||
return nil;
|
||||
}
|
||||
if(strlen((char*)xdata) >= SnarfSize){
|
||||
XFree(xdata);
|
||||
return nil;
|
||||
}
|
||||
strcpy(snarf, (char*)xdata);
|
||||
free(snarf);
|
||||
snarf = strdup((char*)xdata);
|
||||
XFree(xdata);
|
||||
return snarf;
|
||||
}
|
||||
|
||||
@@ -286,8 +282,16 @@ appleputsnarf(void)
|
||||
#ifdef __APPLE__
|
||||
CFDataRef cfdata;
|
||||
PasteboardSyncFlags flags;
|
||||
int n;
|
||||
|
||||
runesnprint(rsnarf, nelem(rsnarf), "%s", snarf);
|
||||
if(snarf == nil)
|
||||
return;
|
||||
n = utflen(snarf) + 1;
|
||||
free(rsnarf);
|
||||
rsnarf = malloc(n * sizeof(Rune));
|
||||
if(rsnarf == nil)
|
||||
return;
|
||||
runesnprint(rsnarf, n, "%s", snarf);
|
||||
if(PasteboardClear(appleclip) != noErr){
|
||||
fprint(2, "apple pasteboard clear failed\n");
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user