Skip to content

Commit 3f04bbf

Browse files
Do not use corrupt cache entries
1 parent 06b2dfe commit 3f04bbf

1 file changed

Lines changed: 38 additions & 7 deletions

File tree

requests.c

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,18 @@ try_init_from_cache(Request *req)
232232
HINTERNET hUrl;
233233
SYSTEMTIME modifiedTimeSys;
234234
FILETIME modifiedTimeFile;
235+
DWORD contentLength;
235236
bool success;
237+
bool deleteCache;
236238

237239
success = false;
240+
deleteCache = false;
238241
hUrl = NULL;
239242
lenlen = sizeof(INTERNET_CACHE_ENTRY_INFOA) + MAX_URL_LENGTH + MAX_PATH;
240243
cacheData = malloc(lenlen);
244+
245+
logmsg("Checking cache for %s\n", req->url);
246+
241247
retry:
242248
if (!RetrieveUrlCacheEntryFileA(req->url, cacheData, &lenlen, 0)) {
243249
err = GetLastError();
@@ -251,30 +257,55 @@ try_init_from_cache(Request *req)
251257
goto cleanup;
252258
}
253259

254-
/* If we have internet, check the last modified time of the resource. If it's newer than what we have cached, bail. */
255260
hUrl = InternetOpenUrlA(hInternet, req->url, NULL, 0,
256261
INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL);
257-
lenlen = sizeof(modifiedTimeSys);
258-
if (hUrl != NULL
259-
&& HttpQueryInfoA(hUrl, HTTP_QUERY_FLAG_SYSTEMTIME | HTTP_QUERY_LAST_MODIFIED, &modifiedTimeSys, &lenlen, 0)
260-
&& SystemTimeToFileTime(&modifiedTimeSys, &modifiedTimeFile)
261-
&& CompareFileTime(&modifiedTimeFile, &cacheData->LastModifiedTime) == 1) {
262-
goto cleanup;
262+
263+
/* If we have internet, check the validity of the cached file. */
264+
if (hUrl != NULL) {
265+
/* If the remote file is newer than what we have cached, bail. */
266+
lenlen = sizeof(modifiedTimeSys);
267+
if (HttpQueryInfoA(hUrl, HTTP_QUERY_FLAG_SYSTEMTIME | HTTP_QUERY_LAST_MODIFIED, &modifiedTimeSys, &lenlen, 0)
268+
&& SystemTimeToFileTime(&modifiedTimeSys, &modifiedTimeFile)
269+
&& CompareFileTime(&modifiedTimeFile, &cacheData->LastModifiedTime) == 1) {
270+
goto cleanup;
271+
}
263272
}
264273

265274
hFile = CreateFileA(cacheData->lpszLocalFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
266275
if (hFile == INVALID_HANDLE_VALUE) {
267276
goto cleanup;
268277
}
269278

279+
/* Compare actual file size on disk against Content-Length to catch truncation. */
280+
if (hUrl != NULL) {
281+
DWORD fileSize = GetFileSize(hFile, NULL);
282+
lenlen = sizeof(contentLength);
283+
if (fileSize != INVALID_FILE_SIZE
284+
&& HttpQueryInfoA(hUrl, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_CONTENT_LENGTH, &contentLength, &lenlen, 0)
285+
&& fileSize != contentLength) {
286+
logmsg("Cache file size mismatch for %s: on disk %d, expected %d\n",
287+
req->url, fileSize, contentLength);
288+
CloseHandle(hFile);
289+
deleteCache = true;
290+
goto cleanup;
291+
}
292+
}
293+
270294
req->handles.hFile = hFile;
271295
req->source = REQ_SRC_CACHE;
272296
req->sizeHint = cacheData->dwSizeLow;
273297
success = true;
274298

299+
logmsg("Initialized from cache: %s\n", req->url);
300+
logmsg(" Cache file: %s\n", cacheData->lpszLocalFileName);
301+
275302
cleanup:
276303
if (!success) {
277304
UnlockUrlCacheEntryFileA(req->url, 0);
305+
if (deleteCache) {
306+
DeleteUrlCacheEntryA(req->url);
307+
logmsg("Deleted cache entry for %s\n", req->url);
308+
}
278309
}
279310
if (hUrl != NULL) {
280311
InternetCloseHandle(hUrl);

0 commit comments

Comments
 (0)