Exemple #1
0
uint32_t
ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, int32_t aYStride,
                       const gfx::IntSize& aCbCrSize, int32_t aCbCrStride,
                       uint32_t aYOffset, uint32_t aCbOffset,
                       uint32_t aCrOffset)
{
  MOZ_ASSERT(aYSize.height >= 0 && aYSize.width >= 0);

  if (aYSize.height < 0 || aYSize.width < 0 || aCbCrSize.height < 0 || aCbCrSize.width < 0 ||
      !gfx::Factory::AllowedSurfaceSize(IntSize(aYStride, aYSize.height)) ||
      !gfx::Factory::AllowedSurfaceSize(IntSize(aCbCrStride, aCbCrSize.height))) {
    return 0;
  }

  uint32_t yLength = GetAlignedStride<4>(aYStride, aYSize.height);
  uint32_t cbCrLength = GetAlignedStride<4>(aCbCrStride, aCbCrSize.height);
  if (yLength == 0 || cbCrLength == 0) {
    return 0;
  }

  CheckedInt<uint32_t> yEnd = aYOffset;
  yEnd += yLength;
  CheckedInt<uint32_t> cbEnd = aCbOffset;
  cbEnd += cbCrLength;
  CheckedInt<uint32_t> crEnd = aCrOffset;
  crEnd += cbCrLength;

  if (!yEnd.isValid() || !cbEnd.isValid() || !crEnd.isValid() ||
      yEnd.value() > aCbOffset || cbEnd.value() > aCrOffset) {
    return 0;
  }

  return crEnd.value();
}
Exemple #2
0
size_t
LZ4::compressLimitedOutput(const char* aSource, size_t aInputSize, char* aDest,
                           size_t aMaxOutputSize)
{
  CheckedInt<int> inputSizeChecked = aInputSize;
  MOZ_ASSERT(inputSizeChecked.isValid());
  CheckedInt<int> maxOutputSizeChecked = aMaxOutputSize;
  MOZ_ASSERT(maxOutputSizeChecked.isValid());
  return LZ4_compress_limitedOutput(aSource, aDest, inputSizeChecked.value(),
                                    maxOutputSizeChecked.value());
}
Exemple #3
0
static bool
DecodeMemory(JSContext* cx, Decoder& d, ModuleGenerator& mg, MutableHandle<ArrayBufferObject*> heap)
{
    uint32_t sectionStart;
    if (!d.startSection(MemoryId, &sectionStart))
        return Fail(cx, d, "failed to start section");
    if (sectionStart == Decoder::NotStarted)
        return true;

    uint32_t initialSizePages;
    if (!d.readVarU32(&initialSizePages))
        return Fail(cx, d, "expected initial memory size");

    CheckedInt<int32_t> initialSize = initialSizePages;
    initialSize *= PageSize;
    if (!initialSize.isValid())
        return Fail(cx, d, "initial memory size too big");

    uint32_t maxSizePages;
    if (!d.readVarU32(&maxSizePages))
        return Fail(cx, d, "expected initial memory size");

    CheckedInt<int32_t> maxSize = maxSizePages;
    maxSize *= PageSize;
    if (!maxSize.isValid())
        return Fail(cx, d, "initial memory size too big");

    uint8_t exported;
    if (!d.readFixedU8(&exported))
        return Fail(cx, d, "expected exported byte");

    if (exported) {
        UniqueChars fieldName = DuplicateString("memory");
        if (!fieldName || !mg.addMemoryExport(Move(fieldName)))
            return false;
    }

    if (!d.finishSection(sectionStart))
        return Fail(cx, d, "memory section byte size mismatch");

    bool signalsForOOB = CompileArgs(cx).useSignalHandlersForOOB;
    heap.set(ArrayBufferObject::createForWasm(cx, initialSize.value(), signalsForOOB));
    if (!heap)
        return false;

    mg.initHeapUsage(HeapUsage::Unshared);
    return true;
}
nsresult
mozHunspell::ConvertCharset(const nsAString& aStr, std::string& aDst)
{
  if (NS_WARN_IF(!mEncoder)) {
    return NS_ERROR_NOT_INITIALIZED;
  }

  auto src = MakeSpan(aStr.BeginReading(), aStr.Length());
  CheckedInt<size_t> needed =
    mEncoder->MaxBufferLengthFromUTF16WithoutReplacement(src.Length());
  if (!needed.isValid()) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  aDst.resize(needed.value());

  char* dstPtr = &aDst[0];
  auto dst = MakeSpan(reinterpret_cast<uint8_t*>(dstPtr), needed.value());

  uint32_t result;
  size_t read;
  size_t written;
  Tie(result, read, written) =
    mEncoder->EncodeFromUTF16WithoutReplacement(src, dst, true);
  Unused << read;
  MOZ_ASSERT(result != kOutputFull);
  if (result != kInputEmpty) {
    return NS_ERROR_UENC_NOMAPPING;
  }
  aDst.resize(written);
  mEncoder->Encoding()->NewEncoderInto(*mEncoder);
  return NS_OK;
}
Exemple #5
0
already_AddRefed<mozilla::MediaByteBuffer>
MoofParser::Metadata()
{
  MediaByteRange moov;
  ScanForMetadata(moov);
  CheckedInt<MediaByteBuffer::size_type> moovLength = moov.Length();
  if (!moovLength.isValid() || !moovLength.value()) {
    // No moov, or cannot be used as array size.
    return nullptr;
  }

  RefPtr<MediaByteBuffer> metadata = new MediaByteBuffer();
  if (!metadata->SetLength(moovLength.value(), fallible)) {
    LOG(Moof, "OOM");
    return nullptr;
  }

  RefPtr<BlockingStream> stream = new BlockingStream(mSource);
  size_t read;
  bool rv =
    stream->ReadAt(moov.mStart, metadata->Elements(), moovLength.value(), &read);
  if (!rv || read != moovLength.value()) {
    return nullptr;
  }
  return metadata.forget();
}
void
AllocateAudioBlock(uint32_t aChannelCount, AudioChunk* aChunk)
{
  if (aChunk->mBuffer && !aChunk->mBuffer->IsShared() &&
      aChunk->ChannelCount() == aChannelCount) {
    MOZ_ASSERT(aChunk->mBufferFormat == AUDIO_FORMAT_FLOAT32);
    MOZ_ASSERT(aChunk->mDuration == WEBAUDIO_BLOCK_SIZE);
    // No need to allocate again.
    aChunk->mVolume = 1.0f;
    return;
  }

  CheckedInt<size_t> size = WEBAUDIO_BLOCK_SIZE;
  size *= aChannelCount;
  size *= sizeof(float);
  if (!size.isValid()) {
    MOZ_CRASH();
  }
  // XXX for SIMD purposes we should do something here to make sure the
  // channel buffers are 16-byte aligned.
  nsRefPtr<SharedBuffer> buffer = SharedBuffer::Create(size.value());
  aChunk->mDuration = WEBAUDIO_BLOCK_SIZE;
  aChunk->mChannelData.SetLength(aChannelCount);
  float* data = static_cast<float*>(buffer->Data());
  for (uint32_t i = 0; i < aChannelCount; ++i) {
    aChunk->mChannelData[i] = data + i*WEBAUDIO_BLOCK_SIZE;
  }
  aChunk->mBuffer = buffer.forget();
  aChunk->mVolume = 1.0f;
  aChunk->mBufferFormat = AUDIO_FORMAT_FLOAT32;
}
Exemple #7
0
size_t
LZ4::compress(const char* aSource, size_t aInputSize, char* aDest)
{
  CheckedInt<int> inputSizeChecked = aInputSize;
  MOZ_ASSERT(inputSizeChecked.isValid());
  return LZ4_compress(aSource, aDest, inputSizeChecked.value());
}
Exemple #8
0
void
AudioBuffer::CopyToChannel(JSContext* aJSContext, const Float32Array& aSource,
                           uint32_t aChannelNumber, uint32_t aStartInChannel,
                           ErrorResult& aRv)
{
  aSource.ComputeLengthAndData();

  uint32_t length = aSource.Length();
  CheckedInt<uint32_t> end = aStartInChannel;
  end += length;
  if (aChannelNumber >= NumberOfChannels() ||
      !end.isValid() || end.value() > mLength) {
    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
    return;
  }

  if (!mSharedChannels && JS_GetTypedArrayLength(mJSChannels[aChannelNumber]) != mLength) {
    // The array was probably neutered
    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
    return;
  }

  if (!RestoreJSChannelData(aJSContext)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

  PodMove(JS_GetFloat32ArrayData(mJSChannels[aChannelNumber]) + aStartInChannel,
          aSource.Data(), length);
}
Exemple #9
0
static bool
AstDecodeMemorySection(AstDecodeContext& c)
{
    uint32_t sectionStart, sectionSize;
    if (!c.d.startSection(MemorySectionId, &sectionStart, &sectionSize))
        return AstDecodeFail(c, "failed to start section");
    if (sectionStart == Decoder::NotStarted)
        return true;

    uint32_t initialSizePages;
    if (!c.d.readVarU32(&initialSizePages))
        return AstDecodeFail(c, "expected initial memory size");

    CheckedInt<uint32_t> initialSize = initialSizePages;
    initialSize *= PageSize;
    if (!initialSize.isValid())
        return AstDecodeFail(c, "initial memory size too big");

    uint32_t maxSizePages;
    if (!c.d.readVarU32(&maxSizePages))
        return AstDecodeFail(c, "expected initial memory size");

    CheckedInt<uint32_t> maxSize = maxSizePages;
    maxSize *= PageSize;
    if (!maxSize.isValid())
        return AstDecodeFail(c, "maximum memory size too big");

    uint8_t exported;
    if (!c.d.readFixedU8(&exported))
        return AstDecodeFail(c, "expected exported byte");

    c.initialSizePages.emplace(initialSizePages);
    if (initialSizePages != maxSizePages) {
      c.maxSizePages.emplace(maxSizePages);
    }

    if (exported) {
        AstExport* export_ = new(c.lifo) AstExport(AstName(MOZ_UTF16("memory"), 6));
        if (!export_ || !c.module().append(export_))
            return false;
    }

    if (!c.d.finishSection(sectionStart, sectionSize))
        return AstDecodeFail(c, "memory section byte size mismatch");

    return true;
}
Exemple #10
0
bool
LZ4::decompress(const char* aSource, char* aDest, size_t aOutputSize)
{
  CheckedInt<int> outputSizeChecked = aOutputSize;
  MOZ_ASSERT(outputSizeChecked.isValid());
  int ret = LZ4_decompress_fast(aSource, aDest, outputSizeChecked.value());
  return ret >= 0;
}
Exemple #11
0
PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
{
    RELEASE_ASSERT(byteOffset <= buffer->byteLength());
    CheckedInt<uint32_t> checkedOffset(byteOffset);
    CheckedInt<uint32_t> checkedLength(byteLength);
    CheckedInt<uint32_t> checkedMax = checkedOffset + checkedLength;
    RELEASE_ASSERT(checkedMax.isValid());
    RELEASE_ASSERT(checkedMax.value() <= buffer->byteLength());
    return adoptRef(new DataView(buffer, byteOffset, byteLength));
}
Exemple #12
0
bool
LZ4::decompress(const char* aSource, size_t aInputSize, char* aDest,
                size_t aMaxOutputSize, size_t *aOutputSize)
{
  CheckedInt<int> maxOutputSizeChecked = aMaxOutputSize;
  MOZ_ASSERT(maxOutputSizeChecked.isValid());
  CheckedInt<int> inputSizeChecked = aInputSize;
  MOZ_ASSERT(inputSizeChecked.isValid());

  int ret = LZ4_decompress_safe(aSource, aDest, inputSizeChecked.value(),
                                maxOutputSizeChecked.value());
  if (ret >= 0) {
    *aOutputSize = ret;
    return true;
  }

  *aOutputSize = 0;
  return false;
}
PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
{
    if (byteOffset > buffer->byteLength())
        return 0;
    CheckedInt<uint32_t> checkedOffset(byteOffset);
    CheckedInt<uint32_t> checkedLength(byteLength);
    CheckedInt<uint32_t> checkedMax = checkedOffset + checkedLength;
    if (!checkedMax.isValid() || checkedMax.value() > buffer->byteLength())
        return 0;
    return adoptRef(new DataView(buffer, byteOffset, byteLength));
}
void
ChildSHistory::Go(int32_t aOffset, ErrorResult& aRv)
{
  CheckedInt<int32_t> index = Index();
  index += aOffset;
  if (!index.isValid()) {
    aRv.Throw(NS_ERROR_FAILURE);
    return;
  }
  aRv = mHistory->GotoIndex(index.value());
}
Exemple #15
0
HRESULT
FramesToUsecs(int64_t aSamples, uint32_t aRate, int64_t* aOutUsecs)
{
  MOZ_ASSERT(aOutUsecs);
  CheckedInt<int64_t> i = aSamples;
  i *= USECS_PER_S;
  i /= aRate;
  NS_ENSURE_TRUE(i.isValid(), E_FAIL);
  *aOutUsecs = i.value();
  return S_OK;
}
/* static */
bool
gfxASurface::CheckSurfaceSize(const gfxIntSize& sz, int32_t limit)
{
    if (sz.width < 0 || sz.height < 0) {
        NS_WARNING("Surface width or height < 0!");
        return false;
    }

    // reject images with sides bigger than limit
    if (limit && (sz.width > limit || sz.height > limit)) {
        NS_WARNING("Surface size too large (exceeds caller's limit)!");
        return false;
    }

#if defined(XP_MACOSX)
    // CoreGraphics is limited to images < 32K in *height*,
    // so clamp all surfaces on the Mac to that height
    if (sz.height > SHRT_MAX) {
        NS_WARNING("Surface size too large (exceeds CoreGraphics limit)!");
        return false;
    }
#endif

    // make sure the surface area doesn't overflow a int32_t
    CheckedInt<int32_t> tmp = sz.width;
    tmp *= sz.height;
    if (!tmp.isValid()) {
        NS_WARNING("Surface size too large (would overflow)!");
        return false;
    }

    // assuming 4-byte stride, make sure the allocation size
    // doesn't overflow a int32_t either
    tmp *= 4;
    if (!tmp.isValid()) {
        NS_WARNING("Allocation too large (would overflow)!");
        return false;
    }

    return true;
}
int32_t
ComputeRGBStride(SurfaceFormat aFormat, int32_t aWidth)
{
  CheckedInt<int32_t> size = BytesPerPixel(aFormat);
  size *= aWidth;
  if (!size.isValid() || size.value() <= 0) {
    gfxDebug() << "ComputeStride overflow " << aWidth;
    return 0;
  }

  return GetAlignedStride<4>(size.value());
}
Exemple #18
0
HRESULT
HNsToFrames(int64_t aHNs, uint32_t aRate, int64_t* aOutFrames)
{
  MOZ_ASSERT(aOutFrames);
  const int64_t HNS_PER_S = USECS_PER_S * 10;
  CheckedInt<int64_t> i = aHNs;
  i *= aRate;
  i /= HNS_PER_S;
  NS_ENSURE_TRUE(i.isValid(), E_FAIL);
  *aOutFrames = i.value();
  return S_OK;
}
void
RequestContext::ScheduleUnblock()
{
  MOZ_ASSERT(!IsNeckoChild());
  MOZ_ASSERT(NS_IsMainThread());

  if (!gHttpHandler) {
    return;
  }

  uint32_t quantum = gHttpHandler->TailBlockingDelayQuantum(mAfterDOMContentLoaded);
  uint32_t delayMax = gHttpHandler->TailBlockingDelayMax();
  uint32_t totalMax = gHttpHandler->TailBlockingTotalMax();

  if (!mBeginLoadTime.IsNull()) {
    // We decrease the maximum delay progressively with the time since the page load
    // begin.  This seems like a reasonable and clear heuristic allowing us to start
    // loading tailed requests in a deterministic time after the load has started.

    uint32_t sinceBeginLoad = static_cast<uint32_t>(
      (TimeStamp::NowLoRes() - mBeginLoadTime).ToMilliseconds());
    uint32_t tillTotal = totalMax - std::min(sinceBeginLoad, totalMax);
    uint32_t proportion = totalMax // values clamped between 0 and 60'000
      ? (delayMax * tillTotal) / totalMax
      : 0;
    delayMax = std::min(delayMax, proportion);
  }

  CheckedInt<uint32_t> delay = quantum * mNonTailRequests;

  if (!mAfterDOMContentLoaded) {
    // Before DOMContentLoaded notification we want to make sure that tailed
    // requests don't start when there is a short delay during which we may
    // not have any active requests on the page happening.
    delay += quantum;
  }

  if (!delay.isValid() || delay.value() > delayMax) {
    delay = delayMax;
  }

  LOG(("RequestContext::ScheduleUnblock this=%p non-tails=%u tail-queue=%zu delay=%u after-DCL=%d",
       this, mNonTailRequests, mTailQueue.Length(), delay.value(), mAfterDOMContentLoaded));

  TimeStamp now = TimeStamp::NowLoRes();
  mUntailAt = now + TimeDuration::FromMilliseconds(delay.value());

  if (mTimerScheduledAt.IsNull() || mUntailAt < mTimerScheduledAt) {
    LOG(("RequestContext %p timer would fire too late, rescheduling", this));
    RescheduleUntailTimer(now);
  }
}
Deinterlacer::Deinterlacer(const nsIntSize& aImageSize)
  : mImageSize(aImageSize)
{
  CheckedInt<size_t> bufferSize = mImageSize.width;
  bufferSize *= mImageSize.height;
  bufferSize *= sizeof(uint32_t);

  if (!bufferSize.isValid()) {
    return;
  }

  mBuffer = MakeUniqueFallible<uint8_t[]>(bufferSize.value());
}
already_AddRefed<mozilla::MediaByteBuffer>
MoofParser::Metadata()
{
  MediaByteRange ftyp;
  MediaByteRange moov;
  ScanForMetadata(ftyp, moov);
  CheckedInt<MediaByteBuffer::size_type> ftypLength = ftyp.Length();
  CheckedInt<MediaByteBuffer::size_type> moovLength = moov.Length();
  if (!ftypLength.isValid() || !moovLength.isValid()
      || !ftypLength.value() || !moovLength.value()) {
    // No ftyp or moov, or they cannot be used as array size.
    return nullptr;
  }
  CheckedInt<MediaByteBuffer::size_type> totalLength = ftypLength + moovLength;
  if (!totalLength.isValid()) {
    // Addition overflow, or sum cannot be used as array size.
    return nullptr;
  }
  RefPtr<MediaByteBuffer> metadata = new MediaByteBuffer();
  if (!metadata->SetLength(totalLength.value(), fallible)) {
    // OOM
    return nullptr;
  }

  RefPtr<mp4_demuxer::BlockingStream> stream = new BlockingStream(mSource);
  size_t read;
  bool rv =
    stream->ReadAt(ftyp.mStart, metadata->Elements(), ftypLength.value(), &read);
  if (!rv || read != ftypLength.value()) {
    return nullptr;
  }
  rv =
    stream->ReadAt(moov.mStart, metadata->Elements() + ftypLength.value(), moovLength.value(), &read);
  if (!rv || read != moovLength.value()) {
    return nullptr;
  }
  return metadata.forget();
}
void WebGLContext::UpdateLastUseIndex()
{
    static CheckedInt<uint64_t> sIndex = 0;

    sIndex++;

    // should never happen with 64-bit; trying to handle this would be riskier than
    // not handling it as the handler code would never get exercised.
    if (!sIndex.isValid()) {
        NS_RUNTIMEABORT("Can't believe it's been 2^64 transactions already!");
    }

    mLastUseIndex = sIndex.value();
}
Exemple #23
0
NS_IMETHODIMP
nsConverterInputStream::Init(nsIInputStream* aStream,
                             const char *aCharset,
                             int32_t aBufferSize,
                             char16_t aReplacementChar)
{
    nsAutoCString label;
    if (!aCharset) {
        label.AssignLiteral("UTF-8");
    } else {
        label = aCharset;
    }

    auto encoding = Encoding::ForLabelNoReplacement(label);
    if (!encoding) {
      return NS_ERROR_UCONV_NOCONV;
    }
    // Previously, the implementation auto-switched only
    // between the two UTF-16 variants and only when
    // initialized with an endianness-unspecific label.
    mConverter = encoding->NewDecoder();

    size_t outputBufferSize;
    if (aBufferSize <= 0) {
      aBufferSize = CONVERTER_BUFFER_SIZE;
      outputBufferSize = CONVERTER_BUFFER_SIZE;
    } else {
      // NetUtil.jsm assumes that if buffer size equals
      // the input size, the whole stream will be processed
      // as one readString. This is not true with encoding_rs,
      // because encoding_rs might want to see space for a
      // surrogate pair, so let's compute a larger output
      // buffer length.
      CheckedInt<size_t> needed = mConverter->MaxUTF16BufferLength(aBufferSize);
      if (!needed.isValid()) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
      outputBufferSize = needed.value();
    }

    // set up our buffers.
    if (!mByteData.SetCapacity(aBufferSize, mozilla::fallible) ||
        !mUnicharData.SetLength(outputBufferSize, mozilla::fallible)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }

    mInput = aStream;
    mErrorsAreFatal = !aReplacementChar;
    return NS_OK;
}
 static already_AddRefed<AudioBlockBuffer> Create(uint32_t aChannelCount)
 {
   CheckedInt<size_t> size = WEBAUDIO_BLOCK_SIZE;
   size *= aChannelCount;
   size *= sizeof(float);
   size += sizeof(AudioBlockBuffer);
   if (!size.isValid()) {
     MOZ_CRASH();
   }
   void* m = moz_xmalloc(size.value());
   nsRefPtr<AudioBlockBuffer> p = new (m) AudioBlockBuffer();
   NS_ASSERTION((reinterpret_cast<char*>(p.get() + 1) - reinterpret_cast<char*>(p.get())) % 4 == 0,
                "AudioBlockBuffers should be at least 4-byte aligned");
   return p.forget();
 }
static sk_sp<SkData>
MakeSkData(unsigned char* aData, const IntSize& aSize, int32_t aStride)
{
  CheckedInt<size_t> size = aStride;
  size *= aSize.height;
  if (size.isValid()) {
    void* mem = sk_malloc_flags(size.value(), 0);
    if (mem) {
      if (aData) {
        memcpy(mem, aData, size.value());
      }
      return SkData::MakeFromMalloc(mem, size.value());
    }
  }
  return nullptr;
}
Exemple #26
0
nsresult
FileReader::DoReadData(uint64_t aCount)
{
    MOZ_ASSERT(mAsyncStream);

    if (mDataFormat == FILE_AS_BINARY) {
        //Continuously update our binary string as data comes in
        uint32_t oldLen = mResult.Length();
        NS_ASSERTION(mResult.Length() == mDataLen, "unexpected mResult length");
        if (uint64_t(oldLen) + aCount > UINT32_MAX)
            return NS_ERROR_OUT_OF_MEMORY;
        char16_t *buf = nullptr;
        mResult.GetMutableData(&buf, oldLen + aCount, fallible);
        NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);

        uint32_t bytesRead = 0;
        mAsyncStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
                                   &bytesRead);
        NS_ASSERTION(bytesRead == aCount, "failed to read data");
    }
    else {
        CheckedInt<uint64_t> size = mDataLen;
        size += aCount;

        //Update memory buffer to reflect the contents of the file
        if (!size.isValid() ||
                // PR_Realloc doesn't support over 4GB memory size even if 64-bit OS
                size.value() > UINT32_MAX ||
                size.value() > mTotal) {
            return NS_ERROR_OUT_OF_MEMORY;
        }

        if (mDataFormat != FILE_AS_ARRAYBUFFER) {
            mFileData = (char *) realloc(mFileData, mDataLen + aCount);
            NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
        }

        uint32_t bytesRead = 0;
        mAsyncStream->Read(mFileData + mDataLen, aCount, &bytesRead);
        NS_ASSERTION(bytesRead == aCount, "failed to read data");
    }

    mDataLen += aCount;
    return NS_OK;
}
Exemple #27
0
void
AudioBuffer::CopyFromChannel(const Float32Array& aDestination, uint32_t aChannelNumber,
                             uint32_t aStartInChannel, ErrorResult& aRv)
{
  aDestination.ComputeLengthAndData();

  uint32_t length = aDestination.Length();
  CheckedInt<uint32_t> end = aStartInChannel;
  end += length;
  if (aChannelNumber >= NumberOfChannels() ||
      !end.isValid() || end.value() > Length()) {
    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
    return;
  }

  JS::AutoCheckCannotGC nogc;
  JSObject* channelArray = mJSChannels[aChannelNumber];
  if (channelArray) {
    if (JS_GetTypedArrayLength(channelArray) != Length()) {
      // The array's buffer was detached.
      aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
      return;
    }

    bool isShared = false;
    const float* sourceData =
      JS_GetFloat32ArrayData(channelArray, &isShared, nogc);
    // The sourceData arrays should all have originated in
    // RestoreJSChannelData, where they are created unshared.
    MOZ_ASSERT(!isShared);
    PodMove(aDestination.Data(), sourceData + aStartInChannel, length);
    return;
  }

  if (!mSharedChannels.IsNull()) {
    CopyChannelDataToFloat(mSharedChannels, aChannelNumber, aStartInChannel,
                           aDestination.Data(), length);
    return;
  }

  PodZero(aDestination.Data(), length);
}
Exemple #28
0
uint32_t
Table::grow(uint32_t delta, JSContext* cx)
{
    // This isn't just an optimization: movingGrowable() assumes that
    // onMovingGrowTable does not fire when length == maximum.
    if (!delta)
        return length_;

    uint32_t oldLength = length_;

    CheckedInt<uint32_t> newLength = oldLength;
    newLength += delta;
    if (!newLength.isValid() || newLength.value() > MaxTableLength)
        return -1;

    if (maximum_ && newLength.value() > maximum_.value())
        return -1;

    MOZ_ASSERT(movingGrowable());

    JSRuntime* rt = cx;  // Use JSRuntime's MallocProvider to avoid throwing.

    // Note that realloc does not release array_'s pointee (which is returned by
    // externalArray()) on failure which is exactly what we need here.
    ExternalTableElem* newArray = rt->pod_realloc(externalArray(), length_, newLength.value());
    if (!newArray)
        return -1;
    Unused << array_.release();
    array_.reset((uint8_t*)newArray);

    // Realloc does not zero the delta for us.
    PodZero(newArray + length_, delta);
    length_ = newLength.value();

    if (observers_.initialized()) {
        for (InstanceSet::Range r = observers_.all(); !r.empty(); r.popFront())
            r.front()->instance().onMovingGrowTable();
    }

    return oldLength;
}
uint32_t
ImageDataSerializerBase::ComputeMinBufferSize(IntSize aSize,
                                              SurfaceFormat aFormat)
{
  MOZ_ASSERT(aSize.height >= 0 && aSize.width >= 0);
  if (aSize.height <= 0 || aSize.width <= 0) {
    gfxDebug() << "Non-positive image buffer size request " << aSize.width << "x" << aSize.height;
    return 0;
  }

  CheckedInt<int32_t> bufsize = ComputeStride(aFormat, aSize.width);
  bufsize *= aSize.height;

  if (!bufsize.isValid() || bufsize.value() <= 0) {
    gfxDebug() << "Buffer size overflow " << aSize.width << "x" << aSize.height;
    return 0;
  }

  return SurfaceBufferInfo::GetOffset()
       + GetAlignedStride<16>(bufsize.value());
}
// While timevaladd is widely available to work with timevals, the newer
// timespec structure is largely lacking such conveniences. Thankfully, the
// utilities available in MFBT make implementing our own quite easy.
static void
moz_timespecadd(struct timespec* lhs, struct timespec* rhs, struct timespec* result)
{
  // Add nanoseconds. This may wrap, but not above 2 billion.
  MOZ_RELEASE_ASSERT(lhs->tv_nsec < NanoSecPerSec);
  MOZ_RELEASE_ASSERT(rhs->tv_nsec < NanoSecPerSec);
  result->tv_nsec = lhs->tv_nsec + rhs->tv_nsec;

  // Add seconds, checking for overflow in the platform specific time_t type.
  CheckedInt<time_t> sec = CheckedInt<time_t>(lhs->tv_sec) + rhs->tv_sec;

  // If nanoseconds overflowed, carry the result over into seconds.
  if (result->tv_nsec >= NanoSecPerSec) {
    MOZ_RELEASE_ASSERT(result->tv_nsec < 2 * NanoSecPerSec);
    result->tv_nsec -= NanoSecPerSec;
    sec += 1;
  }

  // Extracting the value asserts that there was no overflow.
  MOZ_RELEASE_ASSERT(sec.isValid());
  result->tv_sec = sec.value();
}