diff --git a/cups/http-private.h b/cups/http-private.h
index f2640f1..b7f9b6e 100644
--- a/cups/http-private.h
+++ b/cups/http-private.h
@@ -380,6 +380,7 @@ extern const char *_httpResolveURI(const char *uri, char *resolved_uri,
int (*cb)(void *context),
void *context);
extern int _httpUpdate(http_t *http, http_status_t *status);
+extern size_t _httpTLSPending(http_t *http);
extern int _httpWait(http_t *http, int msec, int usessl);
extern void _httpTLSSetOptions(int options);
diff --git a/cups/http.c b/cups/http.c
index e02b66d..128a52a 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -1817,7 +1817,7 @@ httpPrintf(http_t *http, /* I - Connection to server */
...) /* I - Additional args as needed */
{
int bytes; /* Number of bytes to write */
- char buf[16384]; /* Buffer for formatted string */
+ char buf[65536]; /* Buffer for formatted string */
va_list ap; /* Variable argument pointer */
@@ -1829,7 +1829,12 @@ httpPrintf(http_t *http, /* I - Connection to server */
DEBUG_printf(("3httpPrintf: %s", buf));
- if (http->data_encoding == HTTP_ENCODE_FIELDS)
+ if (bytes > (ssize_t)(sizeof(buf) - 1))
+ {
+ http->error = ENOMEM;
+ return (-1);
+ }
+ else if (http->data_encoding == HTTP_ENCODE_FIELDS)
return (httpWrite2(http, buf, bytes));
else
{
diff --git a/cups/ipp.c b/cups/ipp.c
index 0384792..2b613d7 100644
--- a/cups/ipp.c
+++ b/cups/ipp.c
@@ -3847,9 +3847,7 @@ ippSetValueTag(
break;
case IPP_TAG_NAME :
- if (temp_tag != IPP_TAG_KEYWORD && temp_tag != IPP_TAG_URI &&
- temp_tag != IPP_TAG_URISCHEME && temp_tag != IPP_TAG_LANGUAGE &&
- temp_tag != IPP_TAG_MIMETYPE)
+ if (temp_tag != IPP_TAG_KEYWORD)
return (0);
(*attr)->value_tag = (ipp_tag_t)(IPP_TAG_NAME | ((*attr)->value_tag & IPP_TAG_COPY));
@@ -3857,10 +3855,7 @@ ippSetValueTag(
case IPP_TAG_NAMELANG :
case IPP_TAG_TEXTLANG :
- if (value_tag == IPP_TAG_NAMELANG &&
- (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD &&
- temp_tag != IPP_TAG_URI && temp_tag != IPP_TAG_URISCHEME &&
- temp_tag != IPP_TAG_LANGUAGE && temp_tag != IPP_TAG_MIMETYPE))
+ if (value_tag == IPP_TAG_NAMELANG && (temp_tag != IPP_TAG_NAME && temp_tag != IPP_TAG_KEYWORD))
return (0);
if (value_tag == IPP_TAG_TEXTLANG && temp_tag != IPP_TAG_TEXT)
diff --git a/cups/snmp.c b/cups/snmp.c
index 0c0e520..ff4fcd4 100644
--- a/cups/snmp.c
+++ b/cups/snmp.c
@@ -1279,6 +1279,9 @@ asn1_get_integer(
int value; /* Integer value */
+ if (*buffer >= bufend)
+ return (0);
+
if (length > sizeof(int))
{
(*buffer) += length;
@@ -1305,6 +1308,9 @@ asn1_get_length(unsigned char **buffer, /* IO - Pointer in buffer */
unsigned length; /* Length */
+ if (*buffer >= bufend)
+ return (0);
+
length = **buffer;
(*buffer) ++;
@@ -1347,6 +1353,9 @@ asn1_get_oid(
int number; /* OID number */
+ if (*buffer >= bufend)
+ return (0);
+
valend = *buffer + length;
oidptr = oid;
oidend = oid + oidsize - 1;
@@ -1395,9 +1404,12 @@ asn1_get_packed(
int value; /* Value */
+ if (*buffer >= bufend)
+ return (0);
+
value = 0;
- while ((**buffer & 128) && *buffer < bufend)
+ while (*buffer < bufend && (**buffer & 128))
{
value = (value << 7) | (**buffer & 127);
(*buffer) ++;
@@ -1425,6 +1437,9 @@ asn1_get_string(
char *string, /* I - String buffer */
int strsize) /* I - String buffer size */
{
+ if (*buffer >= bufend)
+ return (NULL);
+
if (length > (bufend - *buffer))
length = bufend - *buffer;
@@ -1475,6 +1490,9 @@ asn1_get_type(unsigned char **buffer, /* IO - Pointer in buffer */
int type; /* Type */
+ if (*buffer >= bufend)
+ return (0);
+
type = **buffer;
(*buffer) ++;
diff --git a/scheduler/client.c b/scheduler/client.c
index 6e2f7e6..e20344d 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -770,6 +770,23 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
con->request ? ipp_states[con->request->state] : "",
con->file);
+ if (con->http.error == EPIPE &&
+ (con->http.used == 0
+#ifdef HAVE_SSL
+ || _httpTLSPending(&(con->http)) == 0
+#endif /* HAVE_SSL */
+ ) && recv(con->http.fd, buf, 1, MSG_PEEK) < 1)
+ {
+ /*
+ * Connection closed...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Closing on EOF.", con->http.fd);
+ cupsdCloseClient(con);
+ return;
+ }
+
+
#ifdef HAVE_SSL
if (con->auto_ssl)
{
diff --git a/scheduler/tls-openssl.c b/scheduler/tls-openssl.c
index 759f393..a7a8e85 100644
--- a/scheduler/tls-openssl.c
+++ b/scheduler/tls-openssl.c
@@ -144,6 +144,17 @@ cupsdStartTLS(cupsd_client_t *con) /* I - Client connection */
}
+/*
+ * '_httpTLSPending()' - Return the number of pending TLS-encrypted bytes.
+ */
+
+size_t /* O - Bytes available */
+_httpTLSPending(http_t *http) /* I - HTTP connection */
+{
+ return (SSL_pending(http->tls));
+}
+
+
/*
* 'make_certificate()' - Make a self-signed SSL/TLS certificate.
*/