Example #1
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);
}
Example #2
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());
}
Example #3
0
bool WebGLBuffer::associateBufferSubDataImpl(GC3Dintptr offset, ArrayBuffer* array, GC3Dintptr arrayByteOffset, GC3Dsizeiptr byteLength)
{
    if (!array || offset < 0 || arrayByteOffset < 0 || byteLength < 0)
        return false;

    if (byteLength) {
        CheckedInt<GC3Dintptr> checkedBufferOffset(offset);
        CheckedInt<GC3Dintptr> checkedArrayOffset(arrayByteOffset);
        CheckedInt<GC3Dsizeiptr> checkedLength(byteLength);
        CheckedInt<GC3Dintptr> checkedArrayMax = checkedArrayOffset + checkedLength;
        CheckedInt<GC3Dintptr> checkedBufferMax = checkedBufferOffset + checkedLength;
        if (!checkedArrayMax.valid() || checkedArrayMax.value() > static_cast<int32_t>(array->byteLength()) || !checkedBufferMax.valid() || checkedBufferMax.value() > m_byteLength)
            return false;
    }

    switch (m_target) {
    case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
        clearCachedMaxIndices();
        if (byteLength) {
            if (!m_elementArrayBuffer)
                return false;
            memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()) + offset,
                   static_cast<unsigned char*>(array->data()) + arrayByteOffset,
                   byteLength);
        }
        return true;
    case GraphicsContext3D::ARRAY_BUFFER:
        return true;
    default:
        return false;
    }
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
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;
}
Example #7
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));
}
Example #8
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();
}
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());
}
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));
}
Example #11
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;
}
Example #12
0
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());
}
Example #13
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);
  }
}
Example #15
0
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());
}
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();
}
Example #17
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;
}
Example #18
0
 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();
 }
Example #19
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;
}
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;
}
Example #21
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;
}
Example #22
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;
}
Example #23
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);
}
Example #24
0
/* 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;
}
Example #25
0
bool WebGLBuffer::associateBufferDataImpl(ArrayBuffer* array, GC3Dintptr byteOffset, GC3Dsizeiptr byteLength)
{
    if (byteLength < 0 || byteOffset < 0)
        return false;

    if (array && byteLength) {
        CheckedInt<GC3Dintptr> checkedOffset(byteOffset);
        CheckedInt<GC3Dsizeiptr> checkedLength(byteLength);
        CheckedInt<GC3Dintptr> checkedMax = checkedOffset + checkedLength;
        if (!checkedMax.valid() || checkedMax.value() > static_cast<int32_t>(array->byteLength()))
            return false;
    }

    switch (m_target) {
    case GraphicsContext3D::ELEMENT_ARRAY_BUFFER:
        m_byteLength = byteLength;
        clearCachedMaxIndices();
        if (byteLength) {
            m_elementArrayBuffer = ArrayBuffer::create(byteLength, 1);
            if (!m_elementArrayBuffer) {
                m_byteLength = 0;
                return false;
            }
            if (array) {
                // We must always clone the incoming data because client-side
                // modifications without calling bufferData or bufferSubData
                // must never be able to change the validation results.
                memcpy(static_cast<unsigned char*>(m_elementArrayBuffer->data()),
                       static_cast<unsigned char*>(array->data()) + byteOffset,
                       byteLength);
            }
        } else
            m_elementArrayBuffer = 0;
        return true;
    case GraphicsContext3D::ARRAY_BUFFER:
        m_byteLength = byteLength;
        return true;
    default:
        return false;
    }
}
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());
}
Example #27
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();
}
Example #28
0
// 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();
}
bool
WebGLContext::ValidateDataOffsetSize(WebGLintptr offset, WebGLsizeiptr size, WebGLsizeiptr bufferSize, const char* info)
{
    if (offset < 0) {
        ErrorInvalidValue("%s: offset must be positive", info);
        return false;
    }

    if (size < 0) {
        ErrorInvalidValue("%s: size must be positive", info);
        return false;
    }

    // *** Careful *** WebGLsizeiptr is always 64-bits but GLsizeiptr
    // is like intptr_t. On some platforms it is 32-bits.
    CheckedInt<GLsizeiptr> neededBytes = CheckedInt<GLsizeiptr>(offset) + size;
    if (!neededBytes.isValid() || neededBytes.value() > bufferSize) {
        ErrorInvalidValue("%s: invalid range", info);
        return false;
    }

    return true;
}
Example #30
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 (!RestoreJSChannelData(aJSContext)) {
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    return;
  }

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

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