From 8f14d7223d0bf49fce550a5d18722a6c1d0cc352 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Mon, 9 Dec 2019 21:10:10 -0800 Subject: [PATCH] upnpsoap: Return truncated results on full buffer If our response buffer fills up to the max buffer size on a UPnP Browse request, we should return short results rather than erroring out. Fixes: #314 (Cannot browse MiniDLNA 1.2.1 with VLC 2.2.6 (UPnPError 709: Unsupported or invalid sort criteria)) --- clients.h | 3 ++- upnpsoap.c | 32 +++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/clients.h b/clients.h index cffc7d5..43762bd 100644 --- a/clients.h +++ b/clients.h @@ -40,7 +40,8 @@ #define FLAG_SKIP_DLNA_PN 0x00002000 /* during browsing */ #define FLAG_CONVERT_MS 0x00004000 /* convert ms to s */ /* Response-related flags */ -#define FLAG_HAS_CAPTIONS 0x80000000 +#define FLAG_HAS_CAPTIONS 0x10000000 +#define RESPONSE_TRUNCATED 0x80000000 #define RESPONSE_FLAGS 0xF0000000 enum match_types { diff --git a/upnpsoap.c b/upnpsoap.c index d7db050..744a01b 100644 --- a/upnpsoap.c +++ b/upnpsoap.c @@ -858,15 +858,17 @@ callback(void *args, int argc, char **argv, char **azColName) } else { - DPRINTF(E_ERROR, L_HTTP, "UPnP SOAP response was too big, and realloc failed!\n"); - return -1; + DPRINTF(E_ERROR, L_HTTP, "UPnP SOAP response truncated, realloc failed\n"); + passed_args->flags |= RESPONSE_TRUNCATED; + return 1; } #if MAX_RESPONSE_SIZE > 0 } else { - DPRINTF(E_ERROR, L_HTTP, "UPnP SOAP response cut short, to not exceed the max response size [%lld]!\n", (long long int)MAX_RESPONSE_SIZE); - return -1; + DPRINTF(E_ERROR, L_HTTP, "UPnP SOAP response would exceed the max response size [%lld], truncating\n", (long long int)MAX_RESPONSE_SIZE); + passed_args->flags |= RESPONSE_TRUNCATED; + return 1; } #endif } @@ -1478,12 +1480,19 @@ BrowseContentDirectory(struct upnphttp * h, const char * action) DPRINTF(E_DEBUG, L_HTTP, "Browse SQL: %s\n", sql); ret = sqlite3_exec(db, sql, callback, (void *) &args, &zErrMsg); } - if( (ret != SQLITE_OK) && (zErrMsg != NULL) ) + if( ret != SQLITE_OK ) { - DPRINTF(E_WARN, L_HTTP, "SQL error: %s\nBAD SQL: %s\n", zErrMsg, sql); - sqlite3_free(zErrMsg); - SoapError(h, 709, "Unsupported or invalid sort criteria"); - goto browse_error; + if( args.flags & RESPONSE_TRUNCATED ) + { + sqlite3_free(zErrMsg); + } + else + { + DPRINTF(E_WARN, L_HTTP, "SQL error: %s\nBAD SQL: %s\n", zErrMsg, sql); + sqlite3_free(zErrMsg); + SoapError(h, 709, "Unsupported or invalid sort criteria"); + goto browse_error; + } } sqlite3_free(sql); /* Does the object even exist? */ @@ -1936,9 +1945,10 @@ SearchContentDirectory(struct upnphttp * h, const char * action) orderBy, StartingIndex, RequestedCount); DPRINTF(E_DEBUG, L_HTTP, "Search SQL: %s\n", sql); ret = sqlite3_exec(db, sql, callback, (void *) &args, &zErrMsg); - if( (ret != SQLITE_OK) && (zErrMsg != NULL) ) + if( ret != SQLITE_OK ) { - DPRINTF(E_WARN, L_HTTP, "SQL error: %s\nBAD SQL: %s\n", zErrMsg, sql); + if( !(args.flags & RESPONSE_TRUNCATED) ) + DPRINTF(E_WARN, L_HTTP, "SQL error: %s\nBAD SQL: %s\n", zErrMsg, sql); sqlite3_free(zErrMsg); } sqlite3_free(sql);