bug 318618 avoid useless memcpy in uncompressed case, check for unknown compression methods, r/sr=dougt
This commit is contained in:
Родитель
98b44f7204
Коммит
4049e8dd06
|
@ -50,7 +50,7 @@
|
|||
#include "nsNetUtil.h"
|
||||
|
||||
// just a guess at the max size of the cert.
|
||||
#define MAX_SIGNATURE_SIZE (32*1024)
|
||||
#define MAX_SIGNATURE_SIZE (32*1024)
|
||||
|
||||
|
||||
/*
|
||||
|
@ -77,12 +77,12 @@ static unsigned int xtoint (unsigned char *ii)
|
|||
static unsigned long xtolong (unsigned char *ll)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
|
||||
ret = ((((unsigned long) ll [0]) << 0) |
|
||||
(((unsigned long) ll [1]) << 8) |
|
||||
(((unsigned long) ll [2]) << 16) |
|
||||
(((unsigned long) ll [3]) << 24) );
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -91,31 +91,31 @@ static int my_inflate(unsigned char* compr, PRUint32 comprLen, unsigned char* un
|
|||
int err;
|
||||
z_stream d_stream; /* decompression stream */
|
||||
memset (&d_stream, 0, sizeof (d_stream));
|
||||
|
||||
|
||||
// buffer is way to small to even deal with.
|
||||
if (uncomprLen < 10)
|
||||
return -1;
|
||||
|
||||
*uncompr = '\0';
|
||||
*uncompr = '\0';
|
||||
|
||||
if (inflateInit2 (&d_stream, -MAX_WBITS) != Z_OK)
|
||||
return -1;
|
||||
|
||||
|
||||
d_stream.next_in = compr;
|
||||
d_stream.avail_in = (uInt)comprLen;
|
||||
|
||||
|
||||
d_stream.next_out = uncompr;
|
||||
d_stream.avail_out = (uInt)uncomprLen;
|
||||
|
||||
|
||||
err = inflate(&d_stream, Z_NO_FLUSH);
|
||||
|
||||
if (err != Z_OK && err != Z_STREAM_END) {
|
||||
|
||||
if (err != Z_OK && err != Z_STREAM_END) {
|
||||
inflateEnd(&d_stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
err = inflateEnd(&d_stream);
|
||||
if (err != Z_OK) {
|
||||
if (err != Z_OK) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -133,43 +133,42 @@ CertReader::~CertReader()
|
|||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(CertReader, nsIStreamListener, nsIRequestObserver)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
CertReader::OnStartRequest(nsIRequest *request, nsISupports* context)
|
||||
{
|
||||
mVerifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID);
|
||||
if (!mVerifier)
|
||||
return NS_BINDING_ABORTED;
|
||||
|
||||
|
||||
mLeftoverBuffer.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CertReader::OnDataAvailable(nsIRequest *request,
|
||||
CertReader::OnDataAvailable(nsIRequest *request,
|
||||
nsISupports* context,
|
||||
nsIInputStream *aIStream,
|
||||
nsIInputStream *aIStream,
|
||||
PRUint32 aSourceOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
if (!mVerifier)
|
||||
return NS_BINDING_ABORTED;
|
||||
|
||||
|
||||
char buf[4096];
|
||||
PRUint32 amt, size;
|
||||
nsresult rv;
|
||||
|
||||
while (aLength)
|
||||
|
||||
while (aLength)
|
||||
{
|
||||
size = PR_MIN(aLength, sizeof(buf));
|
||||
|
||||
|
||||
rv = aIStream->Read(buf, size, &amt);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
aLength -= amt;
|
||||
|
||||
|
||||
mLeftoverBuffer.Append(buf, amt);
|
||||
|
||||
if (mLeftoverBuffer.Length() < ZIPLOCAL_SIZE)
|
||||
|
@ -180,10 +179,10 @@ CertReader::OnDataAvailable(nsIRequest *request,
|
|||
ZipLocal_* ziplocal = (ZipLocal_*) caret;
|
||||
|
||||
if (xtolong(ziplocal->signature) != LOCALSIG)
|
||||
return NS_BINDING_ABORTED;
|
||||
return NS_BINDING_ABORTED;
|
||||
|
||||
// did we read the entire file entry into memory?
|
||||
PRUint32 fileEntryLen = (ZIPLOCAL_SIZE +
|
||||
PRUint32 fileEntryLen = (ZIPLOCAL_SIZE +
|
||||
xtoint(ziplocal->filename_len) +
|
||||
xtoint(ziplocal->extrafield_len) +
|
||||
xtolong(ziplocal->size));
|
||||
|
@ -201,46 +200,58 @@ CertReader::OnDataAvailable(nsIRequest *request,
|
|||
|
||||
// the assumption here is that we have the fileEntry in mLeftoverBuffer
|
||||
|
||||
const char* data = (caret +
|
||||
ZIPLOCAL_SIZE +
|
||||
int err = 0;
|
||||
unsigned char* orgData = nsnull;
|
||||
unsigned char* sigData = nsnull;
|
||||
const char* data = (caret +
|
||||
ZIPLOCAL_SIZE +
|
||||
xtoint(ziplocal->filename_len) +
|
||||
xtoint(ziplocal->extrafield_len));
|
||||
|
||||
PRUint32 sigSize = 0;
|
||||
PRUint32 orgSize = xtolong ((unsigned char *) ziplocal->orglen);
|
||||
PRUint32 cSize = xtolong ((unsigned char *) ziplocal->size);
|
||||
|
||||
if (orgSize == 0)
|
||||
return NS_BINDING_ABORTED;
|
||||
switch (xtoint(ziplocal->method))
|
||||
{
|
||||
case STORED:
|
||||
// file is uncompressed, can use the data where it is
|
||||
sigSize = cSize;
|
||||
sigData = (unsigned char*)data;
|
||||
break;
|
||||
|
||||
unsigned char* orgData;
|
||||
int err = 0;
|
||||
case DEFLATED:
|
||||
if (orgSize == 0 || orgSize > MAX_SIGNATURE_SIZE)
|
||||
return NS_BINDING_ABORTED;
|
||||
|
||||
orgData = (unsigned char*) malloc(orgSize);
|
||||
|
||||
if (!orgData)
|
||||
return NS_BINDING_ABORTED;
|
||||
orgData = (unsigned char*)malloc(orgSize);
|
||||
if (!orgData)
|
||||
return NS_BINDING_ABORTED;
|
||||
|
||||
if (xtoint(ziplocal->method) == DEFLATED) {
|
||||
err = my_inflate((unsigned char*)data,
|
||||
cSize,
|
||||
orgData,
|
||||
orgSize);
|
||||
|
||||
err = my_inflate((unsigned char*)data,
|
||||
cSize,
|
||||
orgData,
|
||||
orgSize);
|
||||
}
|
||||
else {
|
||||
memcpy(orgData, data, orgSize);
|
||||
sigSize = orgSize;
|
||||
sigData = orgData;
|
||||
break;
|
||||
|
||||
default:
|
||||
// unsupported compression method
|
||||
err = Z_DATA_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (err == 0)
|
||||
if (err == 0)
|
||||
{
|
||||
PRInt32 verifyError;
|
||||
rv = mVerifier->VerifySignature((char*)orgData, orgSize, nsnull, 0,
|
||||
rv = mVerifier->VerifySignature((char*)sigData, sigSize, nsnull, 0,
|
||||
&verifyError, getter_AddRefs(mPrincipal));
|
||||
}
|
||||
if (orgData)
|
||||
if (orgData)
|
||||
free(orgData);
|
||||
|
||||
|
||||
// Cancel the load now that we've verified the signature
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
|
@ -252,11 +263,11 @@ NS_IMETHODIMP
|
|||
CertReader::OnStopRequest(nsIRequest *request, nsISupports* context,
|
||||
nsresult aStatus)
|
||||
{
|
||||
mObserver->OnCertAvailable(mURI,
|
||||
mContext,
|
||||
mObserver->OnCertAvailable(mURI,
|
||||
mContext,
|
||||
aStatus,
|
||||
mPrincipal);
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче