mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1225004 - Record reason for NS_ERROR_FILE_CORRUPTED in nsLayoutStylesheetCache::LoadSheet in crash reports. r=roc
This commit is contained in:
parent
9841f71f66
commit
79d069eaee
@ -27,6 +27,7 @@
|
|||||||
#include "nsIChromeRegistry.h"
|
#include "nsIChromeRegistry.h"
|
||||||
#include "nsISimpleEnumerator.h"
|
#include "nsISimpleEnumerator.h"
|
||||||
#include "nsISubstitutingProtocolHandler.h"
|
#include "nsISubstitutingProtocolHandler.h"
|
||||||
|
#include "zlib.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
@ -469,6 +470,30 @@ nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_CRASHREPORTER
|
#ifdef MOZ_CRASHREPORTER
|
||||||
|
static inline nsresult
|
||||||
|
ComputeCRC32(nsIFile* aFile, uint32_t* aResult)
|
||||||
|
{
|
||||||
|
PRFileDesc* fd;
|
||||||
|
nsresult rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
uint32_t crc = crc32(0, nullptr, 0);
|
||||||
|
|
||||||
|
unsigned char buf[512];
|
||||||
|
int32_t n;
|
||||||
|
while ((n = PR_Read(fd, buf, sizeof(buf))) > 0) {
|
||||||
|
crc = crc32(crc, buf, n);
|
||||||
|
}
|
||||||
|
PR_Close(fd);
|
||||||
|
|
||||||
|
if (n < 0) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = crc;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ListInterestingFiles(nsString& aAnnotation, nsIFile* aFile,
|
ListInterestingFiles(nsString& aAnnotation, nsIFile* aFile,
|
||||||
const nsTArray<nsString>& aInterestingFilenames)
|
const nsTArray<nsString>& aInterestingFilenames)
|
||||||
@ -488,7 +513,14 @@ ListInterestingFiles(nsString& aAnnotation, nsIFile* aFile,
|
|||||||
} else {
|
} else {
|
||||||
aAnnotation.AppendLiteral("???");
|
aAnnotation.AppendLiteral("???");
|
||||||
}
|
}
|
||||||
aAnnotation.AppendLiteral(" bytes)\n");
|
aAnnotation.AppendLiteral(" bytes, crc32 = ");
|
||||||
|
uint32_t crc;
|
||||||
|
nsresult rv = ComputeCRC32(aFile, &crc);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
aAnnotation.AppendPrintf("0x%08x)\n", crc);
|
||||||
|
} else {
|
||||||
|
aAnnotation.AppendPrintf("error 0x%08x)\n", uint32_t(rv));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -553,6 +585,14 @@ AnnotateCrashReport(nsIURI* aURI)
|
|||||||
annotation.Append(NS_ConvertUTF8toUTF16(spec).get());
|
annotation.Append(NS_ConvertUTF8toUTF16(spec).get());
|
||||||
annotation.Append('\n');
|
annotation.Append('\n');
|
||||||
|
|
||||||
|
annotation.AppendLiteral("NS_ERROR_FILE_CORRUPTION reason: ");
|
||||||
|
if (nsZipArchive::sFileCorruptedReason) {
|
||||||
|
annotation.Append(NS_ConvertUTF8toUTF16(nsZipArchive::sFileCorruptedReason).get());
|
||||||
|
annotation.Append('\n');
|
||||||
|
} else {
|
||||||
|
annotation.AppendLiteral("(none)\n");
|
||||||
|
}
|
||||||
|
|
||||||
// The jar: or file: URL that the sheet's resource: or chrome: URL
|
// The jar: or file: URL that the sheet's resource: or chrome: URL
|
||||||
// resolves to.
|
// resolves to.
|
||||||
if (scheme.EqualsLiteral("resource")) {
|
if (scheme.EqualsLiteral("resource")) {
|
||||||
@ -739,6 +779,7 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsZipArchive::sFileCorruptedReason = nullptr;
|
||||||
nsresult rv = gCSSLoader->LoadSheetSync(aURI, aParsingMode, true,
|
nsresult rv = gCSSLoader->LoadSheetSync(aURI, aParsingMode, true,
|
||||||
getter_AddRefs(aSheet));
|
getter_AddRefs(aSheet));
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
@ -446,14 +446,19 @@ nsJAR::LoadEntry(const nsACString &aFilename, char** aBuf, uint32_t* aBufLen)
|
|||||||
uint64_t len64;
|
uint64_t len64;
|
||||||
rv = manifestStream->Available(&len64);
|
rv = manifestStream->Available(&len64);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
NS_ENSURE_TRUE(len64 < UINT32_MAX, NS_ERROR_FILE_CORRUPTED); // bug 164695
|
if (len64 >= UINT32_MAX) { // bug 164695
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsJAR: invalid manifest size";
|
||||||
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
uint32_t len = (uint32_t)len64;
|
uint32_t len = (uint32_t)len64;
|
||||||
buf = (char*)malloc(len+1);
|
buf = (char*)malloc(len+1);
|
||||||
if (!buf) return NS_ERROR_OUT_OF_MEMORY;
|
if (!buf) return NS_ERROR_OUT_OF_MEMORY;
|
||||||
uint32_t bytesRead;
|
uint32_t bytesRead;
|
||||||
rv = manifestStream->Read(buf, len, &bytesRead);
|
rv = manifestStream->Read(buf, len, &bytesRead);
|
||||||
if (bytesRead != len)
|
if (bytesRead != len) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsJAR: manifest too small";
|
||||||
rv = NS_ERROR_FILE_CORRUPTED;
|
rv = NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
free(buf);
|
free(buf);
|
||||||
return rv;
|
return rv;
|
||||||
@ -539,6 +544,7 @@ nsJAR::ParseManifest()
|
|||||||
if (more)
|
if (more)
|
||||||
{
|
{
|
||||||
mParsedManifest = true;
|
mParsedManifest = true;
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsJAR: duplicate manifests";
|
||||||
return NS_ERROR_FILE_CORRUPTED; // More than one MF file
|
return NS_ERROR_FILE_CORRUPTED; // More than one MF file
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,8 +644,10 @@ nsJAR::ParseOneFile(const char* filebuf, int16_t aFileType)
|
|||||||
curLine.Assign(filebuf, linelen);
|
curLine.Assign(filebuf, linelen);
|
||||||
|
|
||||||
if ( ((aFileType == JAR_MF) && !curLine.Equals(JAR_MF_HEADER) ) ||
|
if ( ((aFileType == JAR_MF) && !curLine.Equals(JAR_MF_HEADER) ) ||
|
||||||
((aFileType == JAR_SF) && !curLine.Equals(JAR_SF_HEADER) ) )
|
((aFileType == JAR_SF) && !curLine.Equals(JAR_SF_HEADER) ) ) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsJAR: invalid manifest header";
|
||||||
return NS_ERROR_FILE_CORRUPTED;
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
//-- Skip header section
|
//-- Skip header section
|
||||||
do {
|
do {
|
||||||
|
@ -58,8 +58,10 @@ nsJARInputStream::InitFile(nsJAR *aJar, nsZipItem *item)
|
|||||||
// Must keep handle to filepointer and mmap structure as long as we need access to the mmapped data
|
// Must keep handle to filepointer and mmap structure as long as we need access to the mmapped data
|
||||||
mFd = aJar->mZip->GetFD();
|
mFd = aJar->mZip->GetFD();
|
||||||
mZs.next_in = (Bytef *)aJar->mZip->GetData(item);
|
mZs.next_in = (Bytef *)aJar->mZip->GetData(item);
|
||||||
if (!mZs.next_in)
|
if (!mZs.next_in) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsJARInputStream: !mZs.next_in";
|
||||||
return NS_ERROR_FILE_CORRUPTED;
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
mZs.avail_in = item->Size();
|
mZs.avail_in = item->Size();
|
||||||
mOutSize = item->RealSize();
|
mOutSize = item->RealSize();
|
||||||
mZs.total_out = 0;
|
mZs.total_out = 0;
|
||||||
@ -266,8 +268,10 @@ nsJARInputStream::ContinueInflate(char* aBuffer, uint32_t aCount,
|
|||||||
|
|
||||||
// now inflate
|
// now inflate
|
||||||
int zerr = inflate(&mZs, Z_SYNC_FLUSH);
|
int zerr = inflate(&mZs, Z_SYNC_FLUSH);
|
||||||
if ((zerr != Z_OK) && (zerr != Z_STREAM_END))
|
if ((zerr != Z_OK) && (zerr != Z_STREAM_END)) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsJARInputStream: error while inflating";
|
||||||
return NS_ERROR_FILE_CORRUPTED;
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
*aBytesRead = (mZs.total_out - oldTotalOut);
|
*aBytesRead = (mZs.total_out - oldTotalOut);
|
||||||
|
|
||||||
@ -280,8 +284,10 @@ nsJARInputStream::ContinueInflate(char* aBuffer, uint32_t aCount,
|
|||||||
inflateEnd(&mZs);
|
inflateEnd(&mZs);
|
||||||
|
|
||||||
// stop returning valid data as soon as we know we have a bad CRC
|
// stop returning valid data as soon as we know we have a bad CRC
|
||||||
if (mOutCrc != mInCrc)
|
if (mOutCrc != mInCrc) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsJARInputStream: crc mismatch";
|
||||||
return NS_ERROR_FILE_CORRUPTED;
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -444,6 +444,7 @@ nsresult nsZipArchive::ExtractFile(nsZipItem *item, const char *outname,
|
|||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
uint8_t* buf = cursor.Read(&count);
|
uint8_t* buf = cursor.Read(&count);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsZipArchive: Read() failed to return a buffer";
|
||||||
rv = NS_ERROR_FILE_CORRUPTED;
|
rv = NS_ERROR_FILE_CORRUPTED;
|
||||||
break;
|
break;
|
||||||
} else if (count == 0) {
|
} else if (count == 0) {
|
||||||
@ -644,22 +645,28 @@ MOZ_WIN_MEM_TRY_BEGIN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!centralOffset)
|
if (!centralOffset) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsZipArchive: no central offset";
|
||||||
return NS_ERROR_FILE_CORRUPTED;
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
buf = startp + centralOffset;
|
buf = startp + centralOffset;
|
||||||
|
|
||||||
// avoid overflow of startp + centralOffset.
|
// avoid overflow of startp + centralOffset.
|
||||||
if (buf < startp)
|
if (buf < startp) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsZipArchive: overflow looking for central directory";
|
||||||
return NS_ERROR_FILE_CORRUPTED;
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
//-- Read the central directory headers
|
//-- Read the central directory headers
|
||||||
uint32_t sig = 0;
|
uint32_t sig = 0;
|
||||||
while (buf + int32_t(sizeof(uint32_t)) <= endp &&
|
while (buf + int32_t(sizeof(uint32_t)) <= endp &&
|
||||||
(sig = xtolong(buf)) == CENTRALSIG) {
|
(sig = xtolong(buf)) == CENTRALSIG) {
|
||||||
// Make sure there is enough data available.
|
// Make sure there is enough data available.
|
||||||
if (endp - buf < ZIPCENTRAL_SIZE)
|
if (endp - buf < ZIPCENTRAL_SIZE) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsZipArchive: central directory too small";
|
||||||
return NS_ERROR_FILE_CORRUPTED;
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
// Read the fixed-size data.
|
// Read the fixed-size data.
|
||||||
ZipCentral* central = (ZipCentral*)buf;
|
ZipCentral* central = (ZipCentral*)buf;
|
||||||
@ -672,9 +679,13 @@ MOZ_WIN_MEM_TRY_BEGIN
|
|||||||
// Sanity check variable sizes and refuse to deal with
|
// Sanity check variable sizes and refuse to deal with
|
||||||
// anything too big: it's likely a corrupt archive.
|
// anything too big: it's likely a corrupt archive.
|
||||||
if (namelen < 1 ||
|
if (namelen < 1 ||
|
||||||
namelen > kMaxNameLength ||
|
namelen > kMaxNameLength) {
|
||||||
buf >= buf + diff || // No overflow
|
nsZipArchive::sFileCorruptedReason = "nsZipArchive: namelen out of range";
|
||||||
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
|
if (buf >= buf + diff || // No overflow
|
||||||
buf >= endp - diff) {
|
buf >= endp - diff) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsZipArchive: overflow looking for next item";
|
||||||
return NS_ERROR_FILE_CORRUPTED;
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,8 +708,10 @@ MOZ_WIN_MEM_TRY_BEGIN
|
|||||||
sig = 0;
|
sig = 0;
|
||||||
} /* while reading central directory records */
|
} /* while reading central directory records */
|
||||||
|
|
||||||
if (sig != ENDSIG)
|
if (sig != ENDSIG) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "nsZipArchive: unexpected sig";
|
||||||
return NS_ERROR_FILE_CORRUPTED;
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
// Make the comment available for consumers.
|
// Make the comment available for consumers.
|
||||||
if (endp - buf >= ZIPEND_SIZE) {
|
if (endp - buf >= ZIPEND_SIZE) {
|
||||||
@ -1213,3 +1226,6 @@ nsZipItemPtr_base::nsZipItemPtr_base(nsZipArchive *aZip,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ const char*
|
||||||
|
nsZipArchive::sFileCorruptedReason = nullptr;
|
||||||
|
@ -102,6 +102,8 @@ class nsZipArchive final
|
|||||||
~nsZipArchive();
|
~nsZipArchive();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const char* sFileCorruptedReason;
|
||||||
|
|
||||||
/** constructing does not open the archive. See OpenArchive() */
|
/** constructing does not open the archive. See OpenArchive() */
|
||||||
nsZipArchive();
|
nsZipArchive();
|
||||||
|
|
||||||
|
@ -233,7 +233,11 @@ FileLocation::Data::Copy(char* aBuf, uint32_t aLen)
|
|||||||
aLen, true);
|
aLen, true);
|
||||||
uint32_t readLen;
|
uint32_t readLen;
|
||||||
cursor.Copy(&readLen);
|
cursor.Copy(&readLen);
|
||||||
return (readLen == aLen) ? NS_OK : NS_ERROR_FILE_CORRUPTED;
|
if (readLen != aLen) {
|
||||||
|
nsZipArchive::sFileCorruptedReason = "FileLocation::Data: insufficient data";
|
||||||
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
#endif // !defined(MOZILLA_XPCOMRT_API)
|
#endif // !defined(MOZILLA_XPCOMRT_API)
|
||||||
return NS_ERROR_NOT_INITIALIZED;
|
return NS_ERROR_NOT_INITIALIZED;
|
||||||
|
Loading…
Reference in New Issue
Block a user