Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commit 13d22506 authored by rswindell's avatar rswindell

Fix-up js_recvline() based on infinite error/log message report from Nelgin:

 term 0087 TLS ERROR 'Unexpected <Unknown type> (24) packet, expected application_data (23)' (-1) popping data
 message repeated 492 times: [ term 0087 TLS ERROR 'Unexpected <Unknown type> (24) packet, expected application_data (23)' (-1) popping data]

When using TLS with a JS Socket object, if there was any kind of data error,
the recvline() method would return a blank string rather than null/undefined.
nntpservice.js just loops when it receives a blank string, so this caused an
infinite loop (with disk-filling error log messages).

First change: if no data has been received (i == 0) and there's any kind of
receive error or timeout or disconnection, just return null. And not undefined,
but null (!) like in v3.15 (before the great JS engine update of 2000-mumble).
Also, there appeared to be a JS_RESUMEREQUEST call missing in the TLS error
return case - so that's another bug fixed.
Commented on the magic return values for js_sock_read_check()
and js_socket_recv().
Simplified js_sock_read_check() return value a tad: let the caller decide if
they want to do something special based on the value of 'i'.
Added some comments to make this code more readable.

We are now no longer treating the different error return values (0 and -1) from
js_socket_recv() special in this function, but we dont' treat them special in
any of the other calls in this file/object either, so that seems to be the
norm.
parent 8de4c1b7
......@@ -203,6 +203,9 @@ static BOOL js_socket_peek_byte(js_socket_private_t *p)
return FALSE;
}
/* Returns > 0 upon successful data received (even if there was an error or disconnection) */
/* Returns -1 upon error (and no data received) */
/* Returns 0 upon timeout or disconnection (and no data received) */
static ptrdiff_t js_socket_recv(js_socket_private_t *p, void *buf, size_t len, int flags, int timeout)
{
ptrdiff_t total=0;
......@@ -1332,6 +1335,10 @@ js_peek(JSContext *cx, uintN argc, jsval *arglist)
return(JS_TRUE);
}
/* Returns 0 if there is rx data waiting */
/* Returns 1 if the 'timeout' period has elapsed (with no data waiting) */
/* Returns 2 if the socket has been disconnected (regardless of any data waiting) */
/* Returns 3 if there was no rx data waiting and the 'timeout' period has not yet elapsed */
static int
js_sock_read_check(js_socket_private_t *p, time_t start, int32 timeout, int i)
{
......@@ -1344,9 +1351,6 @@ js_sock_read_check(js_socket_private_t *p, time_t start, int32 timeout, int i)
if(!socket_check(p->sock,&rd,NULL,1000)) {
p->last_error=ERROR_VALUE;
if(i==0) {
return 1;
}
return 2;
}
......@@ -1360,6 +1364,7 @@ js_sock_read_check(js_socket_private_t *p, time_t start, int32 timeout, int i)
return 0;
}
/* This method is to return null on error/timeout, not void/undefined */
static JSBool
js_recvline(JSContext *cx, uintN argc, jsval *arglist)
{
......@@ -1375,7 +1380,7 @@ js_recvline(JSContext *cx, uintN argc, jsval *arglist)
js_socket_private_t* p;
jsrefcount rc;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((p=(js_socket_private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
......@@ -1398,34 +1403,30 @@ js_recvline(JSContext *cx, uintN argc, jsval *arglist)
for(i=0;i<len;) {
if(p->session==-1) {
switch(js_sock_read_check(p,start,timeout,i)) {
case 1:
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
case 1: // time-out */
case 2: // disconnected
if(i) { // some data was received before the error/disconnection
len=0; // so break the loop
continue;
}
// no data received, so just return null
JS_RESUMEREQUEST(cx, rc);
free(buf);
return(JS_TRUE); /* time-out */
case 2:
len=0;
continue;
case 3:
return JS_TRUE;
case 3: // no data and no time-out... yet
continue;
}
}
if((got=js_socket_recv(p, &ch, 1, 0, i?1:timeout))!=1) {
if(p->session==-1) {
p->last_error=ERROR_VALUE;
break;
}
else {
if (got == 0) {
free(buf);
return(JS_TRUE); /* time-out */
}
if (got == -1) {
len = 0;
continue;
}
if(p->session == -1)
p->last_error = ERROR_VALUE;
if (i == 0) { // no data received
JS_RESUMEREQUEST(cx, rc);
free(buf); // so return null (not an empty string)
return(JS_TRUE);
}
break;
}
if(ch=='\n' /* && i>=1 */) /* Mar-9-2003: terminate on sole LF */
......
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