/* void onDataAvailable (in nsIRequest aRequest, in nsISupports aContext,
 *                       in nsIInputStream aInputStream,
 *                       in unsigned long aOffset, in unsigned long aCount); */
NS_IMETHODIMP nsDeflateConverter::OnDataAvailable(nsIRequest *aRequest,
                                                  nsISupports *aContext,
                                                  nsIInputStream *aInputStream,
                                                  PRUint32 aOffset,
                                                  PRUint32 aCount)
{
    if (!mListener)
        return NS_ERROR_NOT_INITIALIZED;

    nsAutoArrayPtr<char> buffer(new char[aCount]);
    NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);

    nsresult rv = ZW_ReadData(aInputStream, buffer.get(), aCount);
    NS_ENSURE_SUCCESS(rv, rv);

    // make sure we aren't reading too much
    mZstream.avail_in = aCount;
    mZstream.next_in = (unsigned char*)buffer.get();

    int zerr = Z_OK;
    // deflate loop
    while (mZstream.avail_in > 0 && zerr == Z_OK) {
        zerr = deflate(&mZstream, Z_NO_FLUSH);

        while (mZstream.avail_out == 0) {
            // buffer is full, push the data out to the listener
            rv = PushAvailableData(aRequest, aContext);
            NS_ENSURE_SUCCESS(rv, rv);
            zerr = deflate(&mZstream, Z_NO_FLUSH);
        }
    }

    return NS_OK;
}
Example #2
0
/* void onDataAvailable (in nsIRequest aRequest, in nsISupports aContext,
 *                       in nsIInputStream aInputStream,
 *                       in unsigned long long aOffset, in unsigned long aCount); */
NS_IMETHODIMP nsZipDataStream::OnDataAvailable(nsIRequest *aRequest,
                                               nsISupports *aContext,
                                               nsIInputStream *aInputStream,
                                               uint64_t aOffset,
                                               uint32_t aCount)
{
    if (!mOutput)
        return NS_ERROR_NOT_INITIALIZED;

    nsAutoArrayPtr<char> buffer(new char[aCount]);
    NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);

    nsresult rv = ZW_ReadData(aInputStream, buffer.get(), aCount);
    NS_ENSURE_SUCCESS(rv, rv);

    return ProcessData(aRequest, aContext, buffer.get(), aOffset, aCount);
}
Example #3
0
/*
 * Reads file entries out of an existing zip file.
 */
nsresult nsZipWriter::ReadFile(nsIFile *aFile)
{
    int64_t size;
    nsresult rv = aFile->GetFileSize(&size);
    NS_ENSURE_SUCCESS(rv, rv);

    // If the file is too short, it cannot be a valid archive, thus we fail
    // without even attempting to open it
    NS_ENSURE_TRUE(size > ZIP_EOCDR_HEADER_SIZE, NS_ERROR_FILE_CORRUPTED);

    nsCOMPtr<nsIInputStream> inputStream;
    rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), aFile);
    NS_ENSURE_SUCCESS(rv, rv);

    uint8_t buf[1024];
    int64_t seek = size - 1024;
    uint32_t length = 1024;

    nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(inputStream);

    while (true) {
        if (seek < 0) {
            length += (int32_t)seek;
            seek = 0;
        }

        rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, seek);
        if (NS_FAILED(rv)) {
            inputStream->Close();
            return rv;
        }
        rv = ZW_ReadData(inputStream, (char *)buf, length);
        if (NS_FAILED(rv)) {
            inputStream->Close();
            return rv;
        }

        /*
         * We have to backtrack from the end of the file until we find the
         * CDS signature
         */
        // We know it's at least this far from the end
        for (uint32_t pos = length - ZIP_EOCDR_HEADER_SIZE;
             (int32_t)pos >= 0; pos--) {
            uint32_t sig = PEEK32(buf + pos);
            if (sig == ZIP_EOCDR_HEADER_SIGNATURE) {
                // Skip down to entry count
                pos += 10;
                uint32_t entries = READ16(buf, &pos);
                // Skip past CDS size
                pos += 4;
                mCDSOffset = READ32(buf, &pos);
                uint32_t commentlen = READ16(buf, &pos);

                if (commentlen == 0)
                    mComment.Truncate();
                else if (pos + commentlen <= length)
                    mComment.Assign((const char *)buf + pos, commentlen);
                else {
                    if ((seek + pos + commentlen) > size) {
                        inputStream->Close();
                        return NS_ERROR_FILE_CORRUPTED;
                    }
                    nsAutoArrayPtr<char> field(new char[commentlen]);
                    NS_ENSURE_TRUE(field, NS_ERROR_OUT_OF_MEMORY);
                    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
                                        seek + pos);
                    if (NS_FAILED(rv)) {
                        inputStream->Close();
                        return rv;
                    }
                    rv = ZW_ReadData(inputStream, field.get(), length);
                    if (NS_FAILED(rv)) {
                        inputStream->Close();
                        return rv;
                    }
                    mComment.Assign(field.get(), commentlen);
                }

                rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
                                    mCDSOffset);
                if (NS_FAILED(rv)) {
                    inputStream->Close();
                    return rv;
                }

                for (uint32_t entry = 0; entry < entries; entry++) {
                    nsZipHeader* header = new nsZipHeader();
                    if (!header) {
                        inputStream->Close();
                        mEntryHash.Clear();
                        mHeaders.Clear();
                        return NS_ERROR_OUT_OF_MEMORY;
                    }
                    rv = header->ReadCDSHeader(inputStream);
                    if (NS_FAILED(rv)) {
                        inputStream->Close();
                        mEntryHash.Clear();
                        mHeaders.Clear();
                        return rv;
                    }
                    mEntryHash.Put(header->mName, mHeaders.Count());
                    if (!mHeaders.AppendObject(header))
                        return NS_ERROR_OUT_OF_MEMORY;
                }

                return inputStream->Close();
            }
        }

        if (seek == 0) {
            // We've reached the start with no signature found. Corrupt.
            inputStream->Close();
            return NS_ERROR_FILE_CORRUPTED;
        }

        // Overlap by the size of the end of cdr
        seek -= (1024 - ZIP_EOCDR_HEADER_SIZE);
    }
    // Will never reach here in reality
    NS_NOTREACHED("Loop should never complete");
    return NS_ERROR_UNEXPECTED;
}
Example #4
0
nsresult nsZipHeader::ReadCDSHeader(nsIInputStream *stream)
{
    NS_ASSERTION(!mInited, "Already initalised");

    PRUint8 buf[ZIP_CDS_HEADER_SIZE];

    nsresult rv = ZW_ReadData(stream, (char *)buf, ZIP_CDS_HEADER_SIZE);
    NS_ENSURE_SUCCESS(rv, rv);

    PRUint32 pos = 0;
    PRUint32 signature = READ32(buf, &pos);
    if (signature != ZIP_CDS_HEADER_SIGNATURE)
        return NS_ERROR_FILE_CORRUPTED;

    mVersionMade = READ16(buf, &pos);
    mVersionNeeded = READ16(buf, &pos);
    mFlags = READ16(buf, &pos);
    mMethod = READ16(buf, &pos);
    mTime = READ16(buf, &pos);
    mDate = READ16(buf, &pos);
    mCRC = READ32(buf, &pos);
    mCSize = READ32(buf, &pos);
    mUSize = READ32(buf, &pos);
    PRUint16 namelength = READ16(buf, &pos);
    mFieldLength = READ16(buf, &pos);
    PRUint16 commentlength = READ16(buf, &pos);
    mDisk = READ16(buf, &pos);
    mIAttr = READ16(buf, &pos);
    mEAttr = READ32(buf, &pos);
    mOffset = READ32(buf, &pos);

    if (namelength > 0) {
        nsAutoArrayPtr<char> field(new char[namelength]);
        NS_ENSURE_TRUE(field, NS_ERROR_OUT_OF_MEMORY);
        rv = ZW_ReadData(stream, field.get(), namelength);
        NS_ENSURE_SUCCESS(rv, rv);
        mName.Assign(field, namelength);
    }
    else
        mName = NS_LITERAL_CSTRING("");

    if (mFieldLength > 0) {
        mExtraField = new PRUint8[mFieldLength];
        NS_ENSURE_TRUE(mExtraField, NS_ERROR_OUT_OF_MEMORY);
        rv = ZW_ReadData(stream, (char *)mExtraField.get(), mFieldLength);
        NS_ENSURE_SUCCESS(rv, rv);
    }

    if (commentlength > 0) {
        nsAutoArrayPtr<char> field(new char[commentlength]);
        NS_ENSURE_TRUE(field, NS_ERROR_OUT_OF_MEMORY);
        rv = ZW_ReadData(stream, field.get(), commentlength);
        NS_ENSURE_SUCCESS(rv, rv);
        mComment.Assign(field, commentlength);
    }
    else
        mComment = NS_LITERAL_CSTRING("");

    mInited = PR_TRUE;
    return NS_OK;
}