bug 318618 avoid useless memcpy in uncompressed case, check for unknown compression methods, r/sr=dougt

This commit is contained in:
dveditz%cruzio.com 2006-01-07 04:11:17 +00:00
Родитель 98b44f7204
Коммит 4049e8dd06
1 изменённых файлов: 62 добавлений и 51 удалений

Просмотреть файл

@ -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;
}