template<typename Tok> JS::Result<Ok> BinASTParser<Tok>::checkFunctionClosedVars() { MOZ_ASSERT(parseContext_->isFunctionBox()); MOZ_TRY(checkClosedVars(*parseContext_->innermostScope())); MOZ_TRY(checkClosedVars(parseContext_->functionScope())); if (parseContext_->functionBox()->function()->isNamedLambda()) MOZ_TRY(checkClosedVars(parseContext_->namedLambdaScope())); return Ok(); }
Result<nsString, nsresult> WebExtensionPolicy::GetURL(const nsAString& aPath) const { nsPrintfCString spec("%s://%s/", kProto, mHostname.get()); nsCOMPtr<nsIURI> uri; MOZ_TRY(NS_NewURI(getter_AddRefs(uri), spec)); MOZ_TRY(uri->Resolve(NS_ConvertUTF16toUTF8(aPath), spec)); return NS_ConvertUTF8toUTF16(spec); }
template<typename Tok> JS::Result<ParseNode*> BinASTParser<Tok>::parseAux(const uint8_t* start, const size_t length) { tokenizer_.emplace(cx_, start, length); Directives directives(options().strictOption); GlobalSharedContext globalsc(cx_, ScopeKind::Global, directives, options().extraWarningsOption); BinParseContext globalpc(cx_, this, &globalsc, /* newDirectives = */ nullptr); if (!globalpc.init()) return cx_->alreadyReportedError(); ParseContext::VarScope varScope(cx_, &globalpc, usedNames_); if (!varScope.init(&globalpc)) return cx_->alreadyReportedError(); MOZ_TRY(tokenizer_->readHeader()); ParseNode* result(nullptr); MOZ_TRY_VAR(result, parseProgram()); Maybe<GlobalScope::Data*> bindings = NewGlobalScopeData(cx_, varScope, alloc_, parseContext_); if (!bindings) return cx_->alreadyReportedError(); globalsc.bindings = *bindings; return result; // Magic conversion to Ok. }
Result<Ok, nsresult> CencSampleEncryptionInfoEntry::Init(BoxReader& aReader) { // Skip a reserved byte. MOZ_TRY(aReader->ReadU8()); uint8_t possiblePatternInfo; MOZ_TRY_VAR(possiblePatternInfo, aReader->ReadU8()); uint8_t flag; MOZ_TRY_VAR(flag, aReader->ReadU8()); MOZ_TRY_VAR(mIVSize, aReader->ReadU8()); // Read the key id. uint8_t key; for (uint32_t i = 0; i < kKeyIdSize; ++i) { MOZ_TRY_VAR(key, aReader->ReadU8()); mKeyId.AppendElement(key); } mIsEncrypted = flag != 0; if (mIsEncrypted) { if (mIVSize != 8 && mIVSize != 16) { return Err(NS_ERROR_FAILURE); } } else if (mIVSize != 0) { return Err(NS_ERROR_FAILURE); } return Ok(); }
Result<Ok, nsresult> MemMapSnapshot::Finalize(AutoMemMap& aMem) { MOZ_ASSERT(mInitialized); MOZ_TRY(Freeze(aMem)); mInitialized = false; return Ok(); }
Result<Ok, nsresult> MemMapSnapshot::Init(size_t aSize) { MOZ_ASSERT(!mInitialized); MOZ_TRY(Create(aSize)); mInitialized = true; return Ok(); }
template<typename Tok> JS::Result<ParseNode*> BinASTParser<Tok>::buildFunction(const size_t start, const BinKind kind, ParseNode* name, ParseNode* params, ParseNode* body, FunctionBox* funbox) { TokenPos pos = tokenizer_->pos(start); // Set the argument count for building argument packets. Function.length is handled // by setting the appropriate funbox field during argument parsing. funbox->function()->setArgCount(params ? uint16_t(params->pn_count) : 0); // ParseNode represents the body as concatenated after the params. params->appendWithoutOrderAssumption(body); bool isStatement = kind == BinKind::EagerFunctionDeclaration || kind == BinKind::SkippableFunctionDeclaration; BINJS_TRY_DECL(result, isStatement ? factory_.newFunctionStatement(pos) : factory_.newFunctionExpression(pos)); factory_.setFunctionBox(result, funbox); factory_.setFunctionFormalParametersAndBody(result, params); HandlePropertyName dotThis = cx_->names().dotThis; const bool declareThis = hasUsedName(dotThis) || funbox->bindingsAccessedDynamically() || funbox->isDerivedClassConstructor(); if (declareThis) { ParseContext::Scope& funScope = parseContext_->functionScope(); ParseContext::Scope::AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(dotThis); MOZ_ASSERT(!p); BINJS_TRY(funScope.addDeclaredName(parseContext_, p, dotThis, DeclarationKind::Var, DeclaredNameInfo::npos)); funbox->setHasThisBinding(); // TODO (efaust): This capture will have to come from encoder side for arrow functions. } // Check all our bindings after maybe adding function This. MOZ_TRY(checkFunctionClosedVars()); BINJS_TRY_DECL(bindings, NewFunctionScopeData(cx_, parseContext_->functionScope(), /* hasParameterExprs = */ false, alloc_, parseContext_)); funbox->functionScopeBindings().set(*bindings); if (funbox->function()->isNamedLambda()) { BINJS_TRY_DECL(recursiveBinding, NewLexicalScopeData(cx_, parseContext_->namedLambdaScope(), alloc_, parseContext_)); funbox->namedLambdaBindings().set(*recursiveBinding); } return result; }
template<typename Tok> JS::Result<Ok> BinASTParser<Tok>::parseAndUpdateScopeNames(ParseContext::Scope& scope, DeclarationKind kind) { AutoList guard(*tokenizer_); uint32_t length = 0; MOZ_TRY(tokenizer_->enterList(length, guard)); RootedAtom name(cx_); for (uint32_t i = 0; i < length; ++i) { name = nullptr; MOZ_TRY_VAR(name, tokenizer_->readAtom()); auto ptr = scope.lookupDeclaredNameForAdd(name); if (ptr) return raiseError("Variable redeclaration"); BINJS_TRY(scope.addDeclaredName(parseContext_, ptr, name.get(), kind, tokenizer_->offset())); } MOZ_TRY(guard.done()); return Ok(); }
Result<Ok, nsresult> SinfParser::ParseSchm(Box& aBox) { BoxReader reader(aBox); if (reader->Remaining() < 8) { return Err(NS_ERROR_FAILURE); } MOZ_TRY(reader->ReadU32()); // flags -- ignore MOZ_TRY_VAR(mSinf.mDefaultEncryptionType, reader->ReadU32()); return Ok(); }
template<typename Tok> JS::Result<Ok> BinASTParser<Tok>::parseAndUpdateCapturedNames(const BinKind kind) { // For the moment, we do not attempt to validate the list of captured names. AutoList guard(*tokenizer_); uint32_t length = 0; MOZ_TRY(tokenizer_->enterList(length, guard)); RootedAtom name(cx_); for (uint32_t i = 0; i < length; ++i) { name = nullptr; MOZ_TRY_VAR(name, tokenizer_->readAtom()); if (kind == BinKind::AssertedParameterScope) { MOZ_ASSERT(parseContext_->isFunctionBox()); if (parseContext_->functionBox()->function()->isNamedLambda()) { if (TryMarkCaptureInScope(parseContext_->namedLambdaScope(), name)) continue; } if (!TryMarkCaptureInScope(parseContext_->functionScope(), name)) return raiseUndeclaredCapture(name); continue; } if (kind == BinKind::AssertedVarScope) { if (TryMarkCaptureInScope(parseContext_->varScope(), name)) continue; } if (!TryMarkCaptureInScope(*parseContext_->innermostScope(), name)) return raiseUndeclaredCapture(name); } MOZ_TRY(guard.done()); return Ok(); }
Result<Ok, nsresult> MemMapSnapshot::Create(size_t aSize) { FilePath path; ScopedCloseFile fd(file_util::CreateAndOpenTemporaryShmemFile(&path)); if (!fd) { return Err(NS_ERROR_FAILURE); } if (HANDLE_EINTR(ftruncate(fileno(fd), aSize)) != 0) { return Err(NS_ERROR_FAILURE); } MOZ_TRY(mMem.init(FILEToFileDescriptor(fd), PR_PROT_READWRITE)); mPath.Assign(path.value().data(), path.value().length()); return Ok(); }
Result<Ok, nsresult> MemMapSnapshot::Freeze(AutoMemMap& aMem) { // Delete the shm file after we're done here, whether we succeed or not. The // open file descriptor will keep it alive until all remaining references // are closed, at which point it will be automatically freed. auto cleanup = MakeScopeExit([&]() { PR_Delete(mPath.get()); }); // Make the shm file readonly. This doesn't make a difference in practice, // since we open and share a read-only file descriptor, and then delete the // file. But it doesn't hurt, either. chmod(mPath.get(), 0400); nsCOMPtr<nsIFile> file; MOZ_TRY(NS_NewNativeLocalFile(mPath, /* followLinks = */ false, getter_AddRefs(file))); return aMem.init(file); }
Result<Ok, nsresult> SinfParser::ParseTenc(Box& aBox) { BoxReader reader(aBox); if (reader->Remaining() < 24) { return Err(NS_ERROR_FAILURE); } MOZ_TRY(reader->ReadU32()); // flags -- ignore uint32_t isEncrypted; MOZ_TRY_VAR(isEncrypted, reader->ReadU24()); MOZ_TRY_VAR(mSinf.mDefaultIVSize, reader->ReadU8()); memcpy(mSinf.mDefaultKeyID, reader->Read(16), 16); return Ok(); }
Result<Ok, nsresult> Edts::Parse(Box& aBox) { Box child = aBox.FirstChild(); if (!child.IsType("elst")) { return Err(NS_ERROR_FAILURE); } BoxReader reader(child); uint32_t flags; MOZ_TRY_VAR(flags, reader->ReadU32()); uint8_t version = flags >> 24; bool emptyEntry = false; uint32_t entryCount; MOZ_TRY_VAR(entryCount, reader->ReadU32()); for (uint32_t i = 0; i < entryCount; i++) { uint64_t segment_duration; int64_t media_time; if (version == 1) { MOZ_TRY_VAR(segment_duration, reader->ReadU64()); MOZ_TRY_VAR(media_time, reader->Read64()); } else { uint32_t tmp; MOZ_TRY_VAR(tmp, reader->ReadU32()); segment_duration = tmp; int32_t tmp2; MOZ_TRY_VAR(tmp2, reader->Read32()); media_time = tmp2; } if (media_time == -1 && i) { LOG(Edts, "Multiple empty edit, not handled"); } else if (media_time == -1) { mEmptyOffset = segment_duration; emptyEntry = true; } else if (i > 1 || (i > 0 && !emptyEntry)) { LOG(Edts, "More than one edit entry, not handled. A/V sync will be wrong"); break; } else { mMediaStart = media_time; } MOZ_TRY(reader->ReadU32()); // media_rate_integer and media_rate_fraction } return Ok(); }
Result<bool, nsresult> FrameParser::VBRHeader::ParseXing( BufferReader* aReader) { static const uint32_t XING_TAG = BigEndian::readUint32("Xing"); static const uint32_t INFO_TAG = BigEndian::readUint32("Info"); enum Flags { NUM_FRAMES = 0x01, NUM_BYTES = 0x02, TOC = 0x04, VBR_SCALE = 0x08 }; MOZ_ASSERT(aReader); // Seek backward to the original position before leaving this scope. const size_t prevReaderOffset = aReader->Offset(); auto scopeExit = MakeScopeExit([&] { aReader->Seek(prevReaderOffset); }); // We have to search for the Xing header as its position can change. for (auto res = aReader->PeekU32(); res.isOk() && res.unwrap() != XING_TAG && res.unwrap() != INFO_TAG;) { aReader->Read(1); res = aReader->PeekU32(); } // Skip across the VBR header ID tag. MOZ_TRY(aReader->ReadU32()); mType = XING; uint32_t flags; MOZ_TRY_VAR(flags, aReader->ReadU32()); if (flags & NUM_FRAMES) { uint32_t frames; MOZ_TRY_VAR(frames, aReader->ReadU32()); mNumAudioFrames = Some(frames); } if (flags & NUM_BYTES) { uint32_t bytes; MOZ_TRY_VAR(bytes, aReader->ReadU32()); mNumBytes = Some(bytes); } if (flags & TOC && aReader->Remaining() >= vbr_header::TOC_SIZE) { if (!mNumBytes) { // We don't have the stream size to calculate offsets, skip the TOC. aReader->Read(vbr_header::TOC_SIZE); } else { mTOC.clear(); mTOC.reserve(vbr_header::TOC_SIZE); uint8_t data; for (size_t i = 0; i < vbr_header::TOC_SIZE; ++i) { MOZ_TRY_VAR(data, aReader->ReadU8()); mTOC.push_back(1.0f / 256.0f * data * mNumBytes.value()); } } } if (flags & VBR_SCALE) { uint32_t scale; MOZ_TRY_VAR(scale, aReader->ReadU32()); mScale = Some(scale); } return mType == XING; }