diff --git a/hphp/runtime/vm/verifier/check_func.cpp b/hphp/runtime/vm/verifier/check_func.cpp index 3d700587e..860224f02 100644 --- a/hphp/runtime/vm/verifier/check_func.cpp +++ b/hphp/runtime/vm/verifier/check_func.cpp @@ -16,7 +16,8 @@ #include #include -#include +#include +#include #include "hphp/runtime/vm/verifier/check.h" #include "hphp/runtime/vm/verifier/cfg.h" @@ -250,13 +251,15 @@ bool FuncChecker::checkSection(bool is_main, const char* name, Offset base, m_instrs.set(offset(pc) - m_func->base()); if (isSwitch(*pc) || instrJumpTarget(bc, offset(pc)) != InvalidAbsoluteOffset) { - if (*pc == OpSwitch) { + if (*pc == OpSwitch && getImm(pc, 2).u_IVA != 0) { int64_t switchBase = getImm(pc, 1).u_I64A; int32_t len = getImmVector(pc).size(); - int64_t limit = base + len - 2; - if (limit < switchBase) { - error("Overflow in Switch bounds [%d:%d]\n", - base, past); + if (len <= 2) { + error("Bounded switch must have a vector of length > 2 [%d:%d]\n", + base, past); + } + if (switchBase > std::numeric_limits::max() - len + 2) { + error("Overflow in Switch bounds [%d:%d]\n", base, past); } } else if (*pc == OpSSwitch) { foreachSwitchString((Opcode*)pc, [&](Id& id) {