void TypeConstraint::verifyFail(const Func* func, int paramNum, const TypedValue* tv) const { Transl::VMRegAnchor _; std::ostringstream fname; fname << func->fullName()->data() << "()"; const StringData* tn = typeName(); if (isSelf()) { selfToTypeName(func, &tn); } else if (isParent()) { parentToTypeName(func, &tn); } auto const givenType = describe_actual_type(tv); if (isExtended()) { // Extended type hints raise warnings instead of recoverable // errors for now, to ease migration (we used to not check these // at all at runtime). assert(nullable() && "only nullable extended type hints are currently supported"); raise_warning( "Argument %d to %s must be of type ?%s, %s given", paramNum + 1, fname.str().c_str(), tn->data(), givenType); } else { raise_recoverable_error( "Argument %d passed to %s must be an instance of %s, %s given", paramNum + 1, fname.str().c_str(), tn->data(), givenType); } }
void raise_recoverable_error(const char *fmt, ...) { std::string msg; va_list ap; va_start(ap, fmt); string_vsnprintf(msg, fmt, ap); va_end(ap); raise_recoverable_error(msg); }
void raise_return_typehint_error(const std::string& msg) { raise_recoverable_error(msg); if (RuntimeOption::EvalCheckReturnTypeHints >= 3 || (RuntimeOption::RepoAuthoritative && Repo::global().HardReturnTypeHints)) { raise_error("Error handler tried to recover from a return typehint " "violation"); } }
void raise_return_typehint_error(const std::string& msg) { if (RuntimeOption::PHP7_EngineExceptions) { VMRegAnchor _; SystemLib::throwTypeErrorObject(msg); } raise_recoverable_error(msg); if (RuntimeOption::EvalCheckReturnTypeHints >= 3) { raise_error("Error handler tried to recover from a return typehint " "violation"); } }
void raise_property_typehint_error(const std::string& msg, bool isSoft) { assertx(RuntimeOption::EvalCheckPropTypeHints > 0); if (RuntimeOption::EvalCheckPropTypeHints == 1 || isSoft) { raise_warning_unsampled(msg); return; } raise_recoverable_error(msg); if (RuntimeOption::EvalCheckPropTypeHints >= 3) { raise_error("Error handler tried to recover from a property typehint " "violation"); } }
void TypeConstraint::verifyFail(const Func* func, int paramNum, const TypedValue* tv) const { Transl::VMRegAnchor _; std::ostringstream fname; fname << func->fullName()->data() << "()"; const StringData* tn = typeName(); if (isSelf()) { selfToTypeName(func, &tn); } else if (isParent()) { parentToTypeName(func, &tn); } auto const givenType = describe_actual_type(tv); if (isExtended()) { if (isSoft()) { // Soft type hints raise warnings instead of recoverable // errors by design, to ease migration. raise_warning( "Argument %d passed to %s must be of type %s, %s given", paramNum + 1, fname.str().c_str(), fullName().c_str(), givenType); } else if (isNullable()) { // This error message is slightly different from the normal case // (fullName() vs tn) raise_recoverable_error( "Argument %d passed to %s must be of type %s, %s given", paramNum + 1, fname.str().c_str(), fullName().c_str(), givenType); } else { assert(false && "Only nullable and soft extended type hints are currently implemented"); } } else { raise_recoverable_error( "Argument %d passed to %s must be an instance of %s, %s given", paramNum + 1, fname.str().c_str(), tn->data(), givenType); } }
static req::ptr<File> phpStreamOpenFilter(const char* sFilter, const String& modestr, int options, const req::ptr<StreamContext>& context) { const char *mode = modestr.c_str(); int rwMode = 0; if (strchr(mode, 'r') || strchr(mode, '+')) { rwMode |= k_STREAM_FILTER_READ; } if (strchr(mode, 'w') || strchr(mode, '+') || strchr(mode, 'a')) { rwMode |= k_STREAM_FILTER_WRITE; } String duppath(sFilter, CopyString); char *path = duppath.mutableData(); char *p = strstr(path, "/resource="); if (!p) { raise_recoverable_error("No URL resource specified"); return nullptr; } auto fp = File::Open(String(p + sizeof("/resource=") - 1, CopyString), modestr, options, context); if (!fp) return nullptr; Resource fpres(fp); *p = 0; char *token = nullptr; p = strtok_r(path + 1, "/", &token); while (p) { if (!strncasecmp(p, "read=", sizeof("read=") - 1)) { phpStreamApplyFilterList(fpres, p + sizeof("read=") - 1, k_STREAM_FILTER_READ); } else if (!strncasecmp(p, "write=", sizeof("write=") - 1)) { phpStreamApplyFilterList(fpres, p + sizeof("write=") - 1, k_STREAM_FILTER_WRITE); } else { phpStreamApplyFilterList(fpres, p, rwMode); } p = strtok_r(nullptr, "/", &token); } return fp; }
static File* phpStreamOpenFilter(const char* sFilter, const String& modestr, int options, const Variant& context) { const char *mode = modestr.c_str(); int rwMode = 0; if (strchr(mode, 'r') || strchr(mode, '+')) { rwMode |= k_STREAM_FILTER_READ; } if (strchr(mode, 'w') || strchr(mode, '+') || strchr(mode, 'a')) { rwMode |= k_STREAM_FILTER_WRITE; } String duppath(sFilter, CopyString); char *path = duppath.bufferSlice().ptr; char *p = strstr(path, "/resource="); if (!p) { raise_recoverable_error("No URL resource specified"); return nullptr; } Resource fpres = File::Open(String(p + sizeof("/resource=") - 1, CopyString), modestr, options, context); if (fpres.isNull()) { return nullptr; } *p = 0; char *token = nullptr; p = strtok_r(path + 1, "/", &token); while (p) { if (!strncasecmp(p, "read=", sizeof("read=") - 1)) { phpStreamApplyFilterList(fpres, p + sizeof("read=") - 1, k_STREAM_FILTER_READ); } else if (!strncasecmp(p, "write=", sizeof("write=") - 1)) { phpStreamApplyFilterList(fpres, p + sizeof("write=") - 1, k_STREAM_FILTER_WRITE); } else { phpStreamApplyFilterList(fpres, p, rwMode); } p = strtok_r(nullptr, "/", &token); } return dynamic_cast<File*>(fpres.detach()); }
void raise_typehint_error(const std::string& msg) { raise_recoverable_error(msg); if (RuntimeOption::RepoAuthoritative && Repo::global().HardTypeHints) { raise_error("Error handler tried to recover from typehint violation"); } }
Variant c_Closure::t___unset(Variant name) { raise_recoverable_error("Closure object cannot have properties"); return init_null(); }
bool c_Closure::t___isset(Variant name) { raise_recoverable_error("Closure object cannot have properties"); return false; }
Variant c_Closure::t___set(Variant member, Variant value) { raise_recoverable_error("Closure object cannot have properties"); return init_null(); }
static Variant eval_for_assert(ActRec* const curFP, const String& codeStr) { String prefixedCode = concat3("<?php return ", codeStr, ";"); auto const oldErrorLevel = s_option_data->assertQuietEval ? HHVM_FN(error_reporting)(Variant(0)) : 0; SCOPE_EXIT { if (s_option_data->assertQuietEval) HHVM_FN(error_reporting)(oldErrorLevel); }; auto const unit = g_context->compileEvalString(prefixedCode.get()); if (unit == nullptr) { raise_recoverable_error("Syntax error in assert()"); // Failure to compile the eval string doesn't count as an // assertion failure. return Variant(true); } if (!(curFP->func()->attrs() & AttrMayUseVV)) { throw_not_supported("assert()", "assert called from non-varenv function"); } if (!curFP->hasVarEnv()) { curFP->setVarEnv(VarEnv::createLocal(curFP)); } auto varEnv = curFP->getVarEnv(); if (curFP != vmfp()) { // If we aren't using FCallBuiltin, the stack frame of the call to assert // will be in middle of the code we are about to eval and our caller, whose // varEnv we want to use. The invokeFunc below will get very confused if // this is the case, since it will be using a varEnv that belongs to the // wrong function on the stack. So, we rebind it here, to match what // invokeFunc will expect. assert(!vmfp()->hasVarEnv()); vmfp()->setVarEnv(varEnv); varEnv->enterFP(curFP, vmfp()); } ObjectData* thiz = nullptr; Class* cls = nullptr; Class* ctx = curFP->func()->cls(); if (ctx) { if (curFP->hasThis()) { thiz = curFP->getThis(); cls = thiz->getVMClass(); } else { cls = curFP->getClass(); } } auto const func = unit->getMain(ctx); return Variant::attach( g_context->invokeFunc( func, init_null_variant, thiz, cls, varEnv, nullptr, ExecutionContext::InvokePseudoMain ) ); }