/* AString convertFromByteArray([const,array,size_is(aCount)] in octet aData, in unsigned long aCount); */ NS_IMETHODIMP nsScriptableUnicodeConverter::ConvertFromByteArray(const uint8_t* aData, uint32_t aCount, nsAString& _retval) { if (!mDecoder) return NS_ERROR_FAILURE; nsresult rv = NS_OK; int32_t inLength = aCount; int32_t outLength; rv = mDecoder->GetMaxLength(reinterpret_cast<const char*>(aData), inLength, &outLength); if (NS_SUCCEEDED(rv)) { PRUnichar* buf = (PRUnichar*)moz_malloc((outLength+1)*sizeof(PRUnichar)); if (!buf) return NS_ERROR_OUT_OF_MEMORY; rv = mDecoder->Convert(reinterpret_cast<const char*>(aData), &inLength, buf, &outLength); if (NS_SUCCEEDED(rv)) { buf[outLength] = 0; _retval.Assign(buf, outLength); } moz_free(buf); return rv; } return NS_ERROR_FAILURE; }
/* void convertToByteArray(in AString aString, [optional] out unsigned long aLen, [array, size_is(aLen),retval] out octet aData); */ NS_IMETHODIMP nsScriptableUnicodeConverter::ConvertToByteArray(const nsAString& aString, uint32_t* aLen, uint8_t** _aData) { char* data; int32_t len; nsresult rv = ConvertFromUnicodeWithLength(aString, &len, &data); if (NS_FAILED(rv)) return rv; nsXPIDLCString str; str.Adopt(data, len); // NOTE: This uses the XPIDLCString as a byte array rv = FinishWithLength(&data, &len); if (NS_FAILED(rv)) return rv; str.Append(data, len); moz_free(data); // NOTE: this being a byte array, it needs no null termination *_aData = reinterpret_cast<uint8_t*>(moz_malloc(str.Length())); if (!*_aData) return NS_ERROR_OUT_OF_MEMORY; memcpy(*_aData, str.get(), str.Length()); *aLen = str.Length(); return NS_OK; }
NS_IMETHODIMP nsBinaryOutputStream::WriteWStringZ(const char16_t* aString) { uint32_t length, byteCount; nsresult rv; length = NS_strlen(aString); rv = Write32(length); if (NS_FAILED(rv)) return rv; if (length == 0) return NS_OK; byteCount = length * sizeof(char16_t); #ifdef IS_BIG_ENDIAN rv = WriteBytes(reinterpret_cast<const char*>(aString), byteCount); #else // XXX use WriteSegments here to avoid copy! char16_t *copy, temp[64]; if (length <= 64) { copy = temp; } else { copy = reinterpret_cast<char16_t*>(moz_malloc(byteCount)); if (!copy) return NS_ERROR_OUT_OF_MEMORY; } NS_ASSERTION((uintptr_t(aString) & 0x1) == 0, "aString not properly aligned"); mozilla::NativeEndian::copyAndSwapToBigEndian(copy, aString, length); rv = WriteBytes(reinterpret_cast<const char*>(copy), byteCount); if (copy != temp) moz_free(copy); #endif return rv; }
nsresult nsScriptableUnicodeConverter::ConvertFromUnicodeWithLength(const nsAString& aSrc, int32_t* aOutLen, char **_retval) { if (!mEncoder) return NS_ERROR_FAILURE; nsresult rv = NS_OK; int32_t inLength = aSrc.Length(); const nsAFlatString& flatSrc = PromiseFlatString(aSrc); rv = mEncoder->GetMaxLength(flatSrc.get(), inLength, aOutLen); if (NS_SUCCEEDED(rv)) { *_retval = (char*)moz_malloc(*aOutLen+1); if (!*_retval) return NS_ERROR_OUT_OF_MEMORY; rv = mEncoder->Convert(flatSrc.get(), &inLength, *_retval, aOutLen); if (NS_SUCCEEDED(rv)) { (*_retval)[*aOutLen] = '\0'; return NS_OK; } moz_free(*_retval); } *_retval = nullptr; return NS_ERROR_FAILURE; }
already_AddRefed<nsIDOMBlob> EncodedBufferCache::ExtractBlob(const nsAString &aContentType) { MutexAutoLock lock(mMutex); nsCOMPtr<nsIDOMBlob> blob; if (mTempFileEnabled) { // generate new temporary file to write blob = new nsDOMTemporaryFileBlob(mFD, 0, mDataSize, aContentType); // fallback to memory blob mTempFileEnabled = false; mDataSize = 0; mFD = nullptr; } else { void* blobData = moz_malloc(mDataSize); NS_ASSERTION(blobData, "out of memory!!"); if (blobData) { for (uint32_t i = 0, offset = 0; i < mEncodedBuffers.Length(); i++) { memcpy((uint8_t*)blobData + offset, mEncodedBuffers.ElementAt(i).Elements(), mEncodedBuffers.ElementAt(i).Length()); offset += mEncodedBuffers.ElementAt(i).Length(); } blob = new nsDOMMemoryFile(blobData, mDataSize, aContentType); mEncodedBuffers.Clear(); } else return nullptr; } mDataSize = 0; return blob.forget(); }
NS_IMETHODIMP nsScriptableInputStream::Read(uint32_t aCount, char** aResult) { nsresult rv = NS_OK; uint64_t count64 = 0; char* buffer = nullptr; if (!mInputStream) { return NS_ERROR_NOT_INITIALIZED; } rv = mInputStream->Available(&count64); if (NS_FAILED(rv)) { return rv; } // bug716556 - Ensure count+1 doesn't overflow uint32_t count = XPCOM_MIN(uint32_t(XPCOM_MIN<uint64_t>(count64, aCount)), uint32_t(UINT32_MAX - 1)); buffer = (char*)moz_malloc(count + 1); // make room for '\0' if (!buffer) { return NS_ERROR_OUT_OF_MEMORY; } rv = ReadHelper(buffer, count); if (NS_FAILED(rv)) { nsMemory::Free(buffer); return rv; } buffer[count] = '\0'; *aResult = buffer; return NS_OK; }
nsresult imgFrame::Init(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, SurfaceFormat aFormat, uint8_t aPaletteDepth /* = 0 */) { // assert for properties that should be verified by decoders, warn for properties related to bad content if (!AllowedImageSize(aWidth, aHeight)) { NS_WARNING("Should have legal image size"); return NS_ERROR_FAILURE; } mOffset.MoveTo(aX, aY); mSize.SizeTo(aWidth, aHeight); mFormat = aFormat; mPaletteDepth = aPaletteDepth; if (aPaletteDepth != 0) { // We're creating for a paletted image. if (aPaletteDepth > 8) { NS_WARNING("Should have legal palette depth"); NS_ERROR("This Depth is not supported"); return NS_ERROR_FAILURE; } // Use the fallible allocator here mPalettedImageData = (uint8_t*)moz_malloc(PaletteDataLength() + GetImageDataLength()); if (!mPalettedImageData) NS_WARNING("moz_malloc for paletted image data should succeed"); NS_ENSURE_TRUE(mPalettedImageData, NS_ERROR_OUT_OF_MEMORY); } else { // Inform the discard tracker that we are going to allocate some memory. if (!DiscardTracker::TryAllocation(4 * mSize.width * mSize.height)) { NS_WARNING("Exceed the hard limit of decode image size"); return NS_ERROR_OUT_OF_MEMORY; } if (!mImageSurface) { mVBuf = AllocateBufferForImage(mSize, mFormat); if (!mVBuf) { return NS_ERROR_OUT_OF_MEMORY; } if (mVBuf->OnHeap()) { int32_t stride = VolatileSurfaceStride(mSize, mFormat); VolatileBufferPtr<uint8_t> ptr(mVBuf); memset(ptr, 0, stride * mSize.height); } mImageSurface = CreateLockedSurface(mVBuf, mSize, mFormat); } if (!mImageSurface) { NS_WARNING("Failed to create VolatileDataSourceSurface"); // Image surface allocation is failed, need to return // the booked buffer size. DiscardTracker::InformDeallocation(4 * mSize.width * mSize.height); return NS_ERROR_OUT_OF_MEMORY; } mInformedDiscardTracker = true; } return NS_OK; }
GenerateBlobRunnable(nsTArray<nsRefPtr<PhotoCallback>>& aCallbacks, uint8_t* aData, uint32_t aLength, const nsAString& aMimeType) : mPhotoDataLength(aLength) { mCallbacks.SwapElements(aCallbacks); mPhotoData = (uint8_t*) moz_malloc(aLength); memcpy(mPhotoData, aData, mPhotoDataLength); mMimeType = aMimeType; }
NS_Alloc(PRSize size) { if (size > PR_INT32_MAX) return nsnull; void* result = moz_malloc(size); if (! result) { // Request an asynchronous flush sGlobalMemory.FlushMemory(NS_LITERAL_STRING("alloc-failure").get(), PR_FALSE); } return result; }
static void GetDataFrom(const T& aObject, uint8_t*& aBuffer, uint32_t& aLength) { MOZ_ASSERT(!aBuffer); aObject.ComputeLengthAndData(); // We use moz_malloc here rather than a FallibleTArray or fallible // operator new[] since the gfxUserFontEntry will be calling moz_free // on it. aBuffer = (uint8_t*) moz_malloc(aObject.Length()); if (!aBuffer) { return; } memcpy((void*) aBuffer, aObject.Data(), aObject.Length()); aLength = aObject.Length(); }
SECItem* CryptoBuffer::ToSECItem() { uint8_t* data = (uint8_t*) moz_malloc(Length()); if (!data) { return nullptr; } SECItem* item = new SECItem(); item->type = siBuffer; item->data = data; item->len = Length(); memcpy(item->data, Elements(), Length()); return item; }
nsresult XULContentSinkImpl::AddText(const PRUnichar* aText, int32_t aLength) { // Create buffer when we first need it if (0 == mTextSize) { mText = (PRUnichar *) moz_malloc(sizeof(PRUnichar) * 4096); if (nullptr == mText) { return NS_ERROR_OUT_OF_MEMORY; } mTextSize = 4096; } // Copy data from string into our buffer; flush buffer when it fills up int32_t offset = 0; while (0 != aLength) { int32_t amount = mTextSize - mTextLength; if (amount > aLength) { amount = aLength; } if (0 == amount) { if (mConstrainSize) { nsresult rv = FlushText(); if (NS_OK != rv) { return rv; } } else { mTextSize += aLength; mText = (PRUnichar *) moz_realloc(mText, sizeof(PRUnichar) * mTextSize); if (nullptr == mText) { return NS_ERROR_OUT_OF_MEMORY; } } } memcpy(&mText[mTextLength],aText + offset, sizeof(PRUnichar) * amount); mTextLength += amount; offset += amount; aLength -= amount; } return NS_OK; }
bool nsGIFDecoder2::SetHold(const uint8_t* buf1, uint32_t count1, const uint8_t* buf2 /* = nullptr */, uint32_t count2 /* = 0 */) { // We have to handle the case that buf currently points to hold uint8_t* newHold = (uint8_t *) moz_malloc(std::max(uint32_t(MIN_HOLD_SIZE), count1 + count2)); if (!newHold) { mGIFStruct.state = gif_error; return false; } memcpy(newHold, buf1, count1); if (buf2) { memcpy(newHold + count1, buf2, count2); } moz_free(mGIFStruct.hold); mGIFStruct.hold = newHold; mGIFStruct.bytes_in_hold = count1 + count2; return true; }
nsresult nsScriptableUnicodeConverter::FinishWithLength(char **_retval, int32_t* aLength) { if (!mEncoder) return NS_ERROR_FAILURE; int32_t finLength = 32; *_retval = (char *)moz_malloc(finLength); if (!*_retval) return NS_ERROR_OUT_OF_MEMORY; nsresult rv = mEncoder->Finish(*_retval, &finLength); if (NS_SUCCEEDED(rv)) *aLength = finLength; else moz_free(*_retval); return rv; }
nsresult nsCollationMacUC::ConvertLocaleICU(nsILocale* aNSLocale, char** aICULocale) { NS_ENSURE_ARG_POINTER(aNSLocale); NS_ENSURE_ARG_POINTER(aICULocale); nsAutoString localeString; nsresult res = aNSLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), localeString); NS_ENSURE_TRUE(NS_SUCCEEDED(res) && !localeString.IsEmpty(), NS_ERROR_FAILURE); NS_LossyConvertUTF16toASCII tmp(localeString); tmp.ReplaceChar('-', '_'); char* locale = (char*)moz_malloc(tmp.Length() + 1); if (!locale) { return NS_ERROR_OUT_OF_MEMORY; } strcpy(locale, tmp.get()); *aICULocale = locale; return NS_OK; }
bool AnalyserNode::FFTAnalysis() { float* inputBuffer; bool allocated = false; if (mWriteIndex == 0) { inputBuffer = mBuffer.Elements(); } else { inputBuffer = static_cast<float*>(moz_malloc(FftSize() * sizeof(float))); if (!inputBuffer) { return false; } memcpy(inputBuffer, mBuffer.Elements() + mWriteIndex, sizeof(float) * (FftSize() - mWriteIndex)); memcpy(inputBuffer + FftSize() - mWriteIndex, mBuffer.Elements(), sizeof(float) * mWriteIndex); allocated = true; } ApplyBlackmanWindow(inputBuffer, FftSize()); mAnalysisBlock.PerformFFT(inputBuffer); // Normalize so than an input sine wave at 0dBfs registers as 0dBfs (undo FFT scaling factor). const double magnitudeScale = 1.0 / FftSize(); for (uint32_t i = 0; i < mOutputBuffer.Length(); ++i) { double scalarMagnitude = NS_hypot(mAnalysisBlock.RealData(i), mAnalysisBlock.ImagData(i)) * magnitudeScale; mOutputBuffer[i] = mSmoothingTimeConstant * mOutputBuffer[i] + (1.0 - mSmoothingTimeConstant) * scalarMagnitude; } if (allocated) { moz_free(inputBuffer); } return true; }
NS_IMETHODIMP nsBinaryInputStream::ReadBytes(uint32_t aLength, char* *_rval) { nsresult rv; uint32_t bytesRead; char* s; s = reinterpret_cast<char*>(moz_malloc(aLength)); if (!s) return NS_ERROR_OUT_OF_MEMORY; rv = Read(s, aLength, &bytesRead); if (NS_FAILED(rv)) { moz_free(s); return rv; } if (bytesRead != aLength) { moz_free(s); return NS_ERROR_FAILURE; } *_rval = s; return NS_OK; }
NS_IMETHODIMP nsBinaryOutputStream::WriteWStringZ(const PRUnichar* aString) { PRUint32 length, byteCount; nsresult rv; length = NS_strlen(aString); rv = Write32(length); if (NS_FAILED(rv)) return rv; if (length == 0) return NS_OK; byteCount = length * sizeof(PRUnichar); #ifdef IS_BIG_ENDIAN rv = WriteBytes(reinterpret_cast<const char*>(aString), byteCount); #else // XXX use WriteSegments here to avoid copy! PRUnichar *copy, temp[64]; if (length <= 64) { copy = temp; } else { copy = reinterpret_cast<PRUnichar*>(moz_malloc(byteCount)); if (!copy) return NS_ERROR_OUT_OF_MEMORY; } NS_ASSERTION((PRUptrdiff(aString) & 0x1) == 0, "aString not properly aligned"); for (PRUint32 i = 0; i < length; i++) copy[i] = NS_SWAP16(aString[i]); rv = WriteBytes(reinterpret_cast<const char*>(copy), byteCount); if (copy != temp) moz_free(copy); #endif return rv; }
already_AddRefed<Promise> Request::ConsumeBody(ConsumeType aType, ErrorResult& aRv) { nsRefPtr<Promise> promise = Promise::Create(mOwner, aRv); if (aRv.Failed()) { return nullptr; } if (BodyUsed()) { aRv.ThrowTypeError(MSG_REQUEST_BODY_CONSUMED_ERROR); return nullptr; } SetBodyUsed(); // While the spec says to do this asynchronously, all the body constructors // right now only accept bodies whose streams are backed by an in-memory // buffer that can be read without blocking. So I think this is fine. nsCOMPtr<nsIInputStream> stream; mRequest->GetBody(getter_AddRefs(stream)); if (!stream) { aRv = NS_NewByteInputStream(getter_AddRefs(stream), "", 0, NS_ASSIGNMENT_COPY); if (aRv.Failed()) { return nullptr; } } AutoJSAPI api; api.Init(mOwner); JSContext* cx = api.cx(); // We can make this assertion because for now we only support memory backed // structures for the body argument for a Request. MOZ_ASSERT(NS_InputStreamIsBuffered(stream)); nsCString buffer; uint64_t len; aRv = stream->Available(&len); if (aRv.Failed()) { return nullptr; } aRv = NS_ReadInputStreamToString(stream, buffer, len); if (aRv.Failed()) { return nullptr; } buffer.SetLength(len); switch (aType) { case CONSUME_ARRAYBUFFER: { JS::Rooted<JSObject*> arrayBuffer(cx); arrayBuffer = ArrayBuffer::Create(cx, buffer.Length(), reinterpret_cast<const uint8_t*>(buffer.get())); JS::Rooted<JS::Value> val(cx); val.setObjectOrNull(arrayBuffer); promise->MaybeResolve(cx, val); return promise.forget(); } case CONSUME_BLOB: { // XXXnsm it is actually possible to avoid these duplicate allocations // for the Blob case by having the Blob adopt the stream's memory // directly, but I've not added a special case for now. // // This is similar to nsContentUtils::CreateBlobBuffer, but also deals // with worker wrapping. uint32_t blobLen = buffer.Length(); void* blobData = moz_malloc(blobLen); nsRefPtr<File> blob; if (blobData) { memcpy(blobData, buffer.BeginReading(), blobLen); blob = File::CreateMemoryFile(GetParentObject(), blobData, blobLen, NS_ConvertUTF8toUTF16(mMimeType)); } else { aRv = NS_ERROR_OUT_OF_MEMORY; return nullptr; } promise->MaybeResolve(blob); return promise.forget(); } case CONSUME_JSON: { nsString decoded; aRv = DecodeUTF8(buffer, decoded); if (aRv.Failed()) { return nullptr; } JS::Rooted<JS::Value> json(cx); if (!JS_ParseJSON(cx, decoded.get(), decoded.Length(), &json)) { JS::Rooted<JS::Value> exn(cx); if (JS_GetPendingException(cx, &exn)) { JS_ClearPendingException(cx); promise->MaybeReject(cx, exn); } } promise->MaybeResolve(cx, json); return promise.forget(); } case CONSUME_TEXT: { nsString decoded; aRv = DecodeUTF8(buffer, decoded); if (aRv.Failed()) { return nullptr; } promise->MaybeResolve(decoded); return promise.forget(); } } NS_NOTREACHED("Unexpected consume body type"); // Silence warnings. return nullptr; }
nsresult nsIndexedToHTML::FormatInputStream(nsIRequest* aRequest, nsISupports *aContext, const nsAString &aBuffer) { nsresult rv = NS_OK; // set up unicode encoder if (!mUnicodeEncoder) { nsXPIDLCString encoding; rv = mParser->GetEncoding(getter_Copies(encoding)); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsICharsetConverterManager> charsetConverterManager; charsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); rv = charsetConverterManager->GetUnicodeEncoder(encoding.get(), getter_AddRefs(mUnicodeEncoder)); if (NS_SUCCEEDED(rv)) rv = mUnicodeEncoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, nullptr, (char16_t)'?'); } } // convert the data with unicode encoder char *buffer = nullptr; int32_t dstLength; if (NS_SUCCEEDED(rv)) { int32_t unicharLength = aBuffer.Length(); rv = mUnicodeEncoder->GetMaxLength(PromiseFlatString(aBuffer).get(), unicharLength, &dstLength); if (NS_SUCCEEDED(rv)) { buffer = (char *) moz_malloc(dstLength); NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY); rv = mUnicodeEncoder->Convert(PromiseFlatString(aBuffer).get(), &unicharLength, buffer, &dstLength); if (NS_SUCCEEDED(rv)) { int32_t finLen = 0; rv = mUnicodeEncoder->Finish(buffer + dstLength, &finLen); if (NS_SUCCEEDED(rv)) dstLength += finLen; } } } // if conversion error then fallback to UTF-8 if (NS_FAILED(rv)) { rv = NS_OK; if (buffer) { nsMemory::Free(buffer); buffer = nullptr; } } nsCOMPtr<nsIInputStream> inputData; if (buffer) { rv = NS_NewCStringInputStream(getter_AddRefs(inputData), Substring(buffer, dstLength)); nsMemory::Free(buffer); NS_ENSURE_SUCCESS(rv, rv); rv = mListener->OnDataAvailable(aRequest, aContext, inputData, 0, dstLength); } else { NS_ConvertUTF16toUTF8 utf8Buffer(aBuffer); rv = NS_NewCStringInputStream(getter_AddRefs(inputData), utf8Buffer); NS_ENSURE_SUCCESS(rv, rv); rv = mListener->OnDataAvailable(aRequest, aContext, inputData, 0, utf8Buffer.Length()); } return (rv); }
void nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) { /* int number_passes; NOT USED */ png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_type; unsigned int channels; png_bytep trans = nullptr; int num_trans = 0; nsPNGDecoder *decoder = static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr)); /* always decode to 24-bit RGB or 32-bit RGBA */ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type); /* Are we too big? */ if (width > MOZ_PNG_MAX_DIMENSION || height > MOZ_PNG_MAX_DIMENSION) longjmp(png_jmpbuf(decoder->mPNG), 1); // Post our size to the superclass decoder->PostSize(width, height); if (decoder->HasError()) { // Setting the size led to an error. longjmp(png_jmpbuf(decoder->mPNG), 1); } if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { int sample_max = (1 << bit_depth); png_color_16p trans_values; png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values); /* libpng doesn't reject a tRNS chunk with out-of-range samples so we check it here to avoid setting up a useless opacity channel or producing unexpected transparent pixels when using libpng-1.2.19 through 1.2.26 (bug #428045) */ if ((color_type == PNG_COLOR_TYPE_GRAY && (int)trans_values->gray > sample_max) || (color_type == PNG_COLOR_TYPE_RGB && ((int)trans_values->red > sample_max || (int)trans_values->green > sample_max || (int)trans_values->blue > sample_max))) { /* clear the tRNS valid flag and release tRNS memory */ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); } else png_set_expand(png_ptr); } if (bit_depth == 16) png_set_scale_16(png_ptr); qcms_data_type inType = QCMS_DATA_RGBA_8; uint32_t intent = -1; uint32_t pIntent; if (decoder->mCMSMode != eCMSMode_Off) { intent = gfxPlatform::GetRenderingIntent(); decoder->mInProfile = PNGGetColorProfile(png_ptr, info_ptr, color_type, &inType, &pIntent); /* If we're not mandating an intent, use the one from the image. */ if (intent == uint32_t(-1)) intent = pIntent; } if (decoder->mInProfile && gfxPlatform::GetCMSOutputProfile()) { qcms_data_type outType; if (color_type & PNG_COLOR_MASK_ALPHA || num_trans) outType = QCMS_DATA_RGBA_8; else outType = QCMS_DATA_RGB_8; decoder->mTransform = qcms_transform_create(decoder->mInProfile, inType, gfxPlatform::GetCMSOutputProfile(), outType, (qcms_intent)intent); } else { png_set_gray_to_rgb(png_ptr); // only do gamma correction if CMS isn't entirely disabled if (decoder->mCMSMode != eCMSMode_Off) PNGDoGammaCorrection(png_ptr, info_ptr); if (decoder->mCMSMode == eCMSMode_All) { if (color_type & PNG_COLOR_MASK_ALPHA || num_trans) decoder->mTransform = gfxPlatform::GetCMSRGBATransform(); else decoder->mTransform = gfxPlatform::GetCMSRGBTransform(); } } /* let libpng expand interlaced images */ if (interlace_type == PNG_INTERLACE_ADAM7) { /* number_passes = */ png_set_interlace_handling(png_ptr); } /* now all of those things we set above are used to update various struct * members and whatnot, after which we can get channels, rowbytes, etc. */ png_read_update_info(png_ptr, info_ptr); decoder->mChannels = channels = png_get_channels(png_ptr, info_ptr); /*---------------------------------------------------------------*/ /* copy PNG info into imagelib structs (formerly png_set_dims()) */ /*---------------------------------------------------------------*/ // This code is currently unused, but it will be needed for bug 517713. #if 0 int32_t alpha_bits = 1; if (channels == 2 || channels == 4) { /* check if alpha is coming from a tRNS chunk and is binary */ if (num_trans) { /* if it's not an indexed color image, tRNS means binary */ if (color_type == PNG_COLOR_TYPE_PALETTE) { for (int i=0; i<num_trans; i++) { if ((trans[i] != 0) && (trans[i] != 255)) { alpha_bits = 8; break; } } } } else { alpha_bits = 8; } } #endif if (channels == 1 || channels == 3) decoder->format = gfx::SurfaceFormat::B8G8R8X8; else if (channels == 2 || channels == 4) decoder->format = gfx::SurfaceFormat::B8G8R8A8; #ifdef PNG_APNG_SUPPORTED if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) png_set_progressive_frame_fn(png_ptr, nsPNGDecoder::frame_info_callback, nullptr); if (png_get_first_frame_is_hidden(png_ptr, info_ptr)) { decoder->mFrameIsHidden = true; } else { #endif decoder->CreateFrame(0, 0, width, height, decoder->format); #ifdef PNG_APNG_SUPPORTED } #endif if (decoder->mTransform && (channels <= 2 || interlace_type == PNG_INTERLACE_ADAM7)) { uint32_t bpp[] = { 0, 3, 4, 3, 4 }; decoder->mCMSLine = (uint8_t *)moz_malloc(bpp[channels] * width); if (!decoder->mCMSLine) { longjmp(png_jmpbuf(decoder->mPNG), 5); // NS_ERROR_OUT_OF_MEMORY } } if (interlace_type == PNG_INTERLACE_ADAM7) { if (height < INT32_MAX / (width * channels)) decoder->interlacebuf = (uint8_t *)moz_malloc(channels * width * height); if (!decoder->interlacebuf) { longjmp(png_jmpbuf(decoder->mPNG), 5); // NS_ERROR_OUT_OF_MEMORY } } if (decoder->NeedsNewFrame()) { /* We know that we need a new frame, so pause input so the decoder * infrastructure can give it to us. */ png_process_data_pause(png_ptr, /* save = */ 1); } }
NS_IMETHODIMP nsCollationMacUC::AllocateRawSortKey(int32_t strength, const nsAString& stringIn, uint8_t** key, uint32_t* outLen) { NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_ARG_POINTER(key); NS_ENSURE_ARG_POINTER(outLen); nsresult res = EnsureCollator(strength); NS_ENSURE_SUCCESS(res, res); uint32_t stringInLen = stringIn.Length(); if (mUseICU) { const UChar* str = (const UChar*)PromiseFlatString(stringIn).get(); int32_t keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, nullptr, 0); NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE); // Since key is freed elsewhere with PR_Free, allocate with PR_Malloc. uint8_t* newKey = (uint8_t*)PR_Malloc(keyLength + 1); if (!newKey) { return NS_ERROR_OUT_OF_MEMORY; } keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, newKey, keyLength + 1); NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE); *key = newKey; *outLen = keyLength; return NS_OK; } uint32_t maxKeyLen = (1 + stringInLen) * kCollationValueSizeFactor * sizeof(UCCollationValue); if (maxKeyLen > mBufferLen) { uint32_t newBufferLen = mBufferLen; do { newBufferLen *= 2; } while (newBufferLen < maxKeyLen); void* newBuffer = moz_malloc(newBufferLen); if (!newBuffer) { return NS_ERROR_OUT_OF_MEMORY; } if (mBuffer) { moz_free(mBuffer); mBuffer = nullptr; } mBuffer = newBuffer; mBufferLen = newBufferLen; } ItemCount actual; OSStatus err = ::UCGetCollationKey(mCollator, (const UniChar*) PromiseFlatString(stringIn).get(), (UniCharCount) stringInLen, (ItemCount) (mBufferLen / sizeof(UCCollationValue)), &actual, (UCCollationValue *)mBuffer); NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE); uint32_t keyLength = actual * sizeof(UCCollationValue); // Since key is freed elsewhere with PR_Free, allocate with PR_Malloc. void* newKey = PR_Malloc(keyLength); if (!newKey) { return NS_ERROR_OUT_OF_MEMORY; } memcpy(newKey, mBuffer, keyLength); *key = (uint8_t *)newKey; *outLen = keyLength; return NS_OK; }
void nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr) { /* int number_passes; NOT USED */ png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_type; unsigned int channels; png_bytep trans = NULL; int num_trans = 0; nsPNGDecoder *decoder = static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr)); /* always decode to 24-bit RGB or 32-bit RGBA */ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type); /* Are we too big? */ if (width > MOZ_PNG_MAX_DIMENSION || height > MOZ_PNG_MAX_DIMENSION) longjmp(png_jmpbuf(decoder->mPNG), 1); // Post our size to the superclass decoder->PostSize(width, height); if (decoder->HasError()) { // Setting the size lead to an error; this can happen when for example // a multipart channel sends an image of a different size. longjmp(png_jmpbuf(decoder->mPNG), 1); } if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { int sample_max = (1 << bit_depth); png_color_16p trans_values; png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values); /* libpng doesn't reject a tRNS chunk with out-of-range samples so we check it here to avoid setting up a useless opacity channel or producing unexpected transparent pixels when using libpng-1.2.19 through 1.2.26 (bug #428045) */ if ((color_type == PNG_COLOR_TYPE_GRAY && (int)trans_values->gray > sample_max) || (color_type == PNG_COLOR_TYPE_RGB && ((int)trans_values->red > sample_max || (int)trans_values->green > sample_max || (int)trans_values->blue > sample_max))) { /* clear the tRNS valid flag and release tRNS memory */ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); } else png_set_expand(png_ptr); } if (bit_depth == 16) png_set_strip_16(png_ptr); qcms_data_type inType; PRUint32 intent = -1; PRUint32 pIntent; if (decoder->mCMSMode != eCMSMode_Off) { intent = gfxPlatform::GetRenderingIntent(); decoder->mInProfile = PNGGetColorProfile(png_ptr, info_ptr, color_type, &inType, &pIntent); /* If we're not mandating an intent, use the one from the image. */ if (intent == PRUint32(-1)) intent = pIntent; } if (decoder->mInProfile && gfxPlatform::GetCMSOutputProfile()) { qcms_data_type outType; if (color_type & PNG_COLOR_MASK_ALPHA || num_trans) outType = QCMS_DATA_RGBA_8; else outType = QCMS_DATA_RGB_8; decoder->mTransform = qcms_transform_create(decoder->mInProfile, inType, gfxPlatform::GetCMSOutputProfile(), outType, (qcms_intent)intent); } else { png_set_gray_to_rgb(png_ptr); // only do gamma correction if CMS isn't entirely disabled if (decoder->mCMSMode != eCMSMode_Off) PNGDoGammaCorrection(png_ptr, info_ptr); if (decoder->mCMSMode == eCMSMode_All) { if (color_type & PNG_COLOR_MASK_ALPHA || num_trans) decoder->mTransform = gfxPlatform::GetCMSRGBATransform(); else decoder->mTransform = gfxPlatform::GetCMSRGBTransform(); } } /* let libpng expand interlaced images */ if (interlace_type == PNG_INTERLACE_ADAM7) { /* number_passes = */ png_set_interlace_handling(png_ptr); } /* now all of those things we set above are used to update various struct * members and whatnot, after which we can get channels, rowbytes, etc. */ png_read_update_info(png_ptr, info_ptr); decoder->mChannels = channels = png_get_channels(png_ptr, info_ptr); /*---------------------------------------------------------------*/ /* copy PNG info into imagelib structs (formerly png_set_dims()) */ /*---------------------------------------------------------------*/ PRInt32 alpha_bits = 1; if (channels == 2 || channels == 4) { /* check if alpha is coming from a tRNS chunk and is binary */ if (num_trans) { /* if it's not an indexed color image, tRNS means binary */ if (color_type == PNG_COLOR_TYPE_PALETTE) { for (int i=0; i<num_trans; i++) { if ((trans[i] != 0) && (trans[i] != 255)) { alpha_bits = 8; break; } } } } else { alpha_bits = 8; } } if (channels == 1 || channels == 3) decoder->format = gfxASurface::ImageFormatRGB24; else if (channels == 2 || channels == 4) decoder->format = gfxASurface::ImageFormatARGB32; #ifdef PNG_APNG_SUPPORTED if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) png_set_progressive_frame_fn(png_ptr, nsPNGDecoder::frame_info_callback, NULL); if (png_get_first_frame_is_hidden(png_ptr, info_ptr)) { decoder->mFrameIsHidden = PR_TRUE; } else { #endif decoder->CreateFrame(0, 0, width, height, decoder->format); #ifdef PNG_APNG_SUPPORTED } #endif if (decoder->mTransform && (channels <= 2 || interlace_type == PNG_INTERLACE_ADAM7)) { PRUint32 bpp[] = { 0, 3, 4, 3, 4 }; decoder->mCMSLine = (PRUint8 *)moz_malloc(bpp[channels] * width); if (!decoder->mCMSLine) { longjmp(png_jmpbuf(decoder->mPNG), 5); // NS_ERROR_OUT_OF_MEMORY } } if (interlace_type == PNG_INTERLACE_ADAM7) { if (height < PR_INT32_MAX / (width * channels)) decoder->interlacebuf = (PRUint8 *)moz_malloc(channels * width * height); if (!decoder->interlacebuf) { longjmp(png_jmpbuf(decoder->mPNG), 5); // NS_ERROR_OUT_OF_MEMORY } } /* Reject any ancillary chunk after IDAT with a bad CRC (bug #397593). * It would be better to show the default frame (if one has already been * successfully decoded) before bailing, but it's simpler to just bail * out with an error message. */ png_set_crc_action(png_ptr, PNG_CRC_NO_CHANGE, PNG_CRC_ERROR_QUIT); return; }
void* Allocate(uint32_t /* unused */, size_t aSize) { return moz_malloc(aSize); }
nsresult imgFrame::Init(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, gfxASurface::gfxImageFormat aFormat, PRUint8 aPaletteDepth /* = 0 */) { // assert for properties that should be verified by decoders, warn for properties related to bad content if (!AllowedImageSize(aWidth, aHeight)) return NS_ERROR_FAILURE; mOffset.MoveTo(aX, aY); mSize.SizeTo(aWidth, aHeight); mFormat = aFormat; mPaletteDepth = aPaletteDepth; if (aPaletteDepth != 0) { // We're creating for a paletted image. if (aPaletteDepth > 8) { NS_ERROR("This Depth is not supported"); return NS_ERROR_FAILURE; } // Use the fallible allocator here mPalettedImageData = (PRUint8*)moz_malloc(PaletteDataLength() + GetImageDataLength()); NS_ENSURE_TRUE(mPalettedImageData, NS_ERROR_OUT_OF_MEMORY); } else { // For Windows, we must create the device surface first (if we're // going to) so that the image surface can wrap it. Can't be done // the other way around. #ifdef USE_WIN_SURFACE if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) { mWinSurface = new gfxWindowsSurface(gfxIntSize(mSize.width, mSize.height), mFormat); if (mWinSurface && mWinSurface->CairoStatus() == 0) { // no error mImageSurface = mWinSurface->GetAsImageSurface(); } else { mWinSurface = nsnull; } } #endif // For other platforms we create the image surface first and then // possibly wrap it in a device surface. This branch is also used // on Windows if we're not using device surfaces or if we couldn't // create one. if (!mImageSurface) mImageSurface = new gfxImageSurface(gfxIntSize(mSize.width, mSize.height), mFormat); if (!mImageSurface || mImageSurface->CairoStatus()) { mImageSurface = nsnull; // guess return NS_ERROR_OUT_OF_MEMORY; } #ifdef XP_MACOSX if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) { mQuartzSurface = new gfxQuartzImageSurface(mImageSurface); } #endif } return NS_OK; }
NS_IMETHODIMP nsHTTPCompressConv::OnDataAvailable(nsIRequest* request, nsISupports *aContext, nsIInputStream *iStr, uint64_t aSourceOffset, uint32_t aCount) { nsresult rv = NS_ERROR_INVALID_CONTENT_ENCODING; uint32_t streamLen = aCount; if (streamLen == 0) { NS_ERROR("count of zero passed to OnDataAvailable"); return NS_ERROR_UNEXPECTED; } if (mStreamEnded) { // Hmm... this may just indicate that the data stream is done and that // what's left is either metadata or padding of some sort.... throwing // it out is probably the safe thing to do. uint32_t n; return iStr->ReadSegments(NS_DiscardSegment, nullptr, streamLen, &n); } switch (mMode) { case HTTP_COMPRESS_GZIP: streamLen = check_header(iStr, streamLen, &rv); if (rv != NS_OK) return rv; if (streamLen == 0) return NS_OK; // FALLTHROUGH case HTTP_COMPRESS_DEFLATE: if (mInpBuffer != nullptr && streamLen > mInpBufferLen) { mInpBuffer = (unsigned char *) moz_realloc(mInpBuffer, mInpBufferLen = streamLen); if (mOutBufferLen < streamLen * 2) mOutBuffer = (unsigned char *) moz_realloc(mOutBuffer, mOutBufferLen = streamLen * 3); if (mInpBuffer == nullptr || mOutBuffer == nullptr) return NS_ERROR_OUT_OF_MEMORY; } if (mInpBuffer == nullptr) mInpBuffer = (unsigned char *) moz_malloc(mInpBufferLen = streamLen); if (mOutBuffer == nullptr) mOutBuffer = (unsigned char *) moz_malloc(mOutBufferLen = streamLen * 3); if (mInpBuffer == nullptr || mOutBuffer == nullptr) return NS_ERROR_OUT_OF_MEMORY; uint32_t unused; iStr->Read((char *)mInpBuffer, streamLen, &unused); if (mMode == HTTP_COMPRESS_DEFLATE) { if (!mStreamInitialized) { memset(&d_stream, 0, sizeof (d_stream)); if (inflateInit(&d_stream) != Z_OK) return NS_ERROR_FAILURE; mStreamInitialized = true; } d_stream.next_in = mInpBuffer; d_stream.avail_in = (uInt)streamLen; mDummyStreamInitialised = false; for (;;) { d_stream.next_out = mOutBuffer; d_stream.avail_out = (uInt)mOutBufferLen; int code = inflate(&d_stream, Z_NO_FLUSH); unsigned bytesWritten = (uInt)mOutBufferLen - d_stream.avail_out; if (code == Z_STREAM_END) { if (bytesWritten) { rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten); if (NS_FAILED (rv)) return rv; } inflateEnd(&d_stream); mStreamEnded = true; break; } else if (code == Z_OK) { if (bytesWritten) { rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten); if (NS_FAILED (rv)) return rv; } } else if (code == Z_BUF_ERROR) { if (bytesWritten) { rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten); if (NS_FAILED (rv)) return rv; } break; } else if (code == Z_DATA_ERROR) { // some servers (notably Apache with mod_deflate) don't generate zlib headers // insert a dummy header and try again static char dummy_head[2] = { 0x8 + 0x7 * 0x10, (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF, }; inflateReset(&d_stream); d_stream.next_in = (Bytef*) dummy_head; d_stream.avail_in = sizeof(dummy_head); code = inflate(&d_stream, Z_NO_FLUSH); if (code != Z_OK) return NS_ERROR_FAILURE; // stop an endless loop caused by non-deflate data being labelled as deflate if (mDummyStreamInitialised) { NS_WARNING("endless loop detected" " - invalid deflate"); return NS_ERROR_INVALID_CONTENT_ENCODING; } mDummyStreamInitialised = true; // reset stream pointers to our original data d_stream.next_in = mInpBuffer; d_stream.avail_in = (uInt)streamLen; } else return NS_ERROR_INVALID_CONTENT_ENCODING; } /* for */ } else { if (!mStreamInitialized) { memset(&d_stream, 0, sizeof (d_stream)); if (inflateInit2(&d_stream, -MAX_WBITS) != Z_OK) return NS_ERROR_FAILURE; mStreamInitialized = true; } d_stream.next_in = mInpBuffer; d_stream.avail_in = (uInt)streamLen; for (;;) { d_stream.next_out = mOutBuffer; d_stream.avail_out = (uInt)mOutBufferLen; int code = inflate (&d_stream, Z_NO_FLUSH); unsigned bytesWritten = (uInt)mOutBufferLen - d_stream.avail_out; if (code == Z_STREAM_END) { if (bytesWritten) { rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten); if (NS_FAILED (rv)) return rv; } inflateEnd(&d_stream); mStreamEnded = true; break; } else if (code == Z_OK) { if (bytesWritten) { rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten); if (NS_FAILED (rv)) return rv; } } else if (code == Z_BUF_ERROR) { if (bytesWritten) { rv = do_OnDataAvailable(request, aContext, aSourceOffset, (char *)mOutBuffer, bytesWritten); if (NS_FAILED (rv)) return rv; } break; } else return NS_ERROR_INVALID_CONTENT_ENCODING; } /* for */ } /* gzip */ break; default: rv = mListener->OnDataAvailable(request, aContext, iStr, aSourceOffset, aCount); if (NS_FAILED (rv)) return rv; } /* switch */ return NS_OK; } /* OnDataAvailable */