Example #1
0
String Variant::toStringHelper() const {
  switch (m_type) {
    case KindOfUninit:
    case KindOfNull:
      return empty_string();

    case KindOfBoolean:
      return m_data.num ? static_cast<String>(s_1)
                        : empty_string();

    case KindOfInt64:
      return m_data.num;

    case KindOfDouble:
      return m_data.dbl;

    case KindOfStaticString:
    case KindOfString:
      assert(false); // Should be done in caller
      return m_data.pstr;

    case KindOfArray:
      raise_notice("Array to string conversion");
      return array_string;

    case KindOfObject:
      return m_data.pobj->invokeToString();

    case KindOfResource:
      return m_data.pres->o_toString();

    case KindOfRef:
      return m_data.pref->var()->toString();

    case KindOfClass:
      break;
  }
  not_reached();
}
Example #2
0
static Variant str_replace(CVarRef search, CVarRef replace, CStrRef subject,
                           int &count, bool caseSensitive) {
  if (search.is(KindOfArray)) {
    String ret = subject;

    Array searchArr = search.toArray();
    if (replace.is(KindOfArray)) {
      Array replArr = replace.toArray();
      ArrayIter replIter(replArr);
      for (ArrayIter iter(searchArr); iter; ++iter) {
        TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE);
        if (replIter) {
          ret = ret.replace(iter.second().toString(),
                            replIter.second().toString(),
                            count, caseSensitive);
          ++replIter;
        } else {
          ret = ret.replace(iter.second().toString(),
                            "", count, caseSensitive);
        }
      }
      return ret;
    }

    TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE);
    String repl = replace.toString();
    for (ArrayIter iter(searchArr); iter; ++iter) {
      ret = ret.replace(iter.second().toString(), repl, count, caseSensitive);
    }
    return ret;
  }

  if (replace.is(KindOfArray)) {
    raise_notice("Array to string conversion");
  }
  TAINT_OBSERVER(TAINT_BIT_MUTATED, TAINT_BIT_NONE);
  return subject.replace(search.toString(), replace.toString(), count,
                         caseSensitive);
}
Example #3
0
bool MySQL::connect(const String& host, int port, const String& socket,
                    const String& username, const String& password,
                    const String& database, int client_flags,
                    int connect_timeout) {
  if (m_conn == nullptr) {
    m_conn = create_new_conn();
  }
  if (connect_timeout >= 0) {
    MySQLUtil::set_mysql_timeout(m_conn, MySQLUtil::ConnectTimeout,
                                 connect_timeout);
  }
  if (RuntimeOption::EnableStats && RuntimeOption::EnableSQLStats) {
    ServerStats::Log("sql.conn", 1);
  }
  IOStatusHelper io("mysql::connect", host.data(), port);
  m_xaction_count = 0;
  if (m_host.empty()) m_host = static_cast<std::string>(host);
  if (m_username.empty()) m_username = static_cast<std::string>(username);
  if (m_password.empty()) m_password = static_cast<std::string>(password);
  if (m_socket.empty()) m_socket = static_cast<std::string>(socket);
  if (m_database.empty()) m_database = static_cast<std::string>(database);
  if (!m_port) m_port = port;
  bool ret = mysql_real_connect(m_conn, host.data(), username.data(),
                            password.data(),
                            (database.empty() ? nullptr : database.data()),
                            port,
                            socket.empty() ? nullptr : socket.data(),
                            client_flags);
  if (ret && mysqlExtension::WaitTimeout > 0) {
    String query("set session wait_timeout=");
    query += String((int64_t)(mysqlExtension::WaitTimeout / 1000));
    if (mysql_real_query(m_conn, query.data(), query.size())) {
      raise_notice("MySQL::connect: failed setting session wait timeout: %s",
                   mysql_error(m_conn));
    }
  }
  m_state = (ret) ? MySQLState::CONNECTED : MySQLState::CLOSED;
  return ret;
}
Example #4
0
  XDEBUG_NOTIMPLEMENTED

static void HHVM_FUNCTION(xdebug_start_code_coverage,
                          int64_t options /* = 0 */) {
  // XDEBUG_CC_UNUSED and XDEBUG_CC_DEAD_CODE not supported right now primarily
  // because the internal CodeCoverage class does support either unexecuted line
  // tracking or dead code analysis
  if (options != 0) {
    raise_error("XDEBUG_CC_UNUSED and XDEBUG_CC_DEAD_CODE constants are not "
                "currently supported.");
    return;
  }

  // If we get here, turn on coverage
  auto ti = ThreadInfo::s_threadInfo.getNoCheck();
  ti->m_reqInjectionData.setCoverage(true);
  if (g_context->isNested()) {
    raise_notice("Calling xdebug_start_code_coverage from a nested VM instance "
                 "may cause unpredicable results");
  }
  throw VMSwitchModeBuiltin();
}
Example #5
0
void tvCastToStringInPlace(TypedValue* tv) {
  assert(tvIsPlausible(*tv));
  tvUnboxIfNeeded(tv);
  StringData * s;
  switch (tv->m_type) {
  case KindOfUninit:
  case KindOfNull:    s = staticEmptyString(); goto static_string;
  case KindOfBoolean:
    s = tv->m_data.num ? s_1.get() : staticEmptyString();
    goto static_string;
  case KindOfInt64:   s = buildStringData(tv->m_data.num); break;
  case KindOfDouble:  s = buildStringData(tv->m_data.dbl); break;
  case KindOfStaticString:
  case KindOfString:  return;
  case KindOfArray:
    raise_notice("Array to string conversion");
    s = array_string.get();
    tvDecRefArr(tv);
    goto static_string;
  case KindOfObject:
    // For objects, we fall back on the Variant machinery
    tvAsVariant(tv) = tv->m_data.pobj->invokeToString();
    return;
  case KindOfResource:
    // For resources, we fall back on the Variant machinery
    tvAsVariant(tv) = tv->m_data.pres->o_toString();
    return;
  default:
    not_reached();
  }

  s->incRefCount();
  tv->m_data.pstr = s;
  tv->m_type = KindOfString;
  return;
static_string:
  tv->m_data.pstr = s;
  tv->m_type = KindOfStaticString;
}
Example #6
0
Variant HHVM_METHOD(XMLReader, expand,
                    const Variant& basenode /* = null */) {
  auto* data = Native::data<XMLReader>(this_);
  Object doc;
  xmlDocPtr docp = nullptr;
  SYNC_VM_REGS_SCOPED();

  if (!basenode.isNull()) {
    DOMNode *dombasenode = toDOMNode(basenode.toObject().get());
    doc = dombasenode->doc();
    docp = (xmlDocPtr) toDOMNode(doc.get())->m_node;
    if (docp == nullptr) {
      raise_warning("Invalid State Error");
      return false;
    }
  } else {
    doc = DOMDocument::newInstance();
  }

  if (data->m_ptr) {
    xmlNodePtr node = xmlTextReaderExpand(data->m_ptr);
    if (node == nullptr) {
      raise_warning("An Error Occurred while expanding");
      return false;
    } else {
      xmlNodePtr nodec = xmlDocCopyNode(node, docp, 1);
      if (nodec == nullptr) {
        raise_notice("Cannot expand this node type");
        return false;
      } else {
        return php_dom_create_object(nodec, doc, false);
      }
    }
  }

  raise_warning("Load Data before trying to read");
  return false;
}
Example #7
0
bool TimeZone::SetCurrent(const char* name) {
  bool valid;
  auto const it = s_tzvCache->find(name);
  if (it != s_tzvCache->end()) {
    valid = it->second;
  } else {
    valid = IsValid(name);

    auto key = strdup(name);
    auto result = s_tzvCache->insert(TimeZoneValidityCacheEntry(key, valid));
    if (!result.second) {
      // The cache is full or a collision occurred, and we don't need our
      // strdup'ed key.
      free(key);
    }
  }

  if (!valid) {
    raise_notice("Timezone ID '%s' is invalid", name);
    return false;
  }
  RID().setTimeZone(name);
  return true;
}
Example #8
0
static Variant warn_non_object() {
  raise_notice("Cannot access property on non-object");
  return uninit_null();
}
Example #9
0
void raise_hackarr_compat_notice(const std::string& msg) {
  if (UNLIKELY(RID().getSuppressHackArrayCompatNotices())) return;
  raise_notice("Hack Array Compat: %s", msg.c_str());
}
Example #10
0
void raise_intish_index_cast() {
  if (UNLIKELY(RID().getSuppressHackArrayCompatNotices())) return;
  raise_notice("Hack Array Compat: Intish index cast");
}
Example #11
0
void raiseArrayKeyNotice(const StringData* key, bool isInOut) {
  raise_notice("Undefined index%s: %s",
               isInOut ? " on inout parameter" : "", key->data());
}
static DataType collator_is_numeric(UChar *str, int length, int64_t *lval,
                                    double *dval, int allow_errors ) {
  int64_t local_lval;
  double local_dval;
  UChar *end_ptr_long, *end_ptr_double;
  int conv_base=10;

  if (!length) {
    return KindOfNull;
  }

  /* handle hex numbers */
  if (length>=2 && str[0]=='0' && (str[1]=='x' || str[1]=='X')) {
    conv_base=16;
  }

  errno=0;
  local_lval = collator_u_strtol(str, &end_ptr_long, conv_base);
  if (errno != ERANGE) {
    if (end_ptr_long == str+length) { /* integer string */
      if (lval) {
        *lval = local_lval;
      }
      return KindOfInt64;
    } else if (end_ptr_long == str &&
               *end_ptr_long != '\0' &&
               *str != '.' &&
               *str != '-') { /* ignore partial string matches */
      return KindOfNull;
    }
  } else {
    end_ptr_long = nullptr;
  }

  if (conv_base == 16) { /* hex string, under UNIX strtod() messes it up */
    /* UTODO: keep compatibility with is_numeric_string() here? */
    return KindOfNull;
  }

  local_dval = collator_u_strtod(str, &end_ptr_double);
  if (local_dval == 0 && end_ptr_double == str) {
    end_ptr_double = nullptr;
  } else {
    if (end_ptr_double == str+length) { /* floating point string */
      if (!finite(local_dval)) {
        /* "inf","nan" and maybe other weird ones */
        return KindOfNull;
      }

      if (dval) {
        *dval = local_dval;
      }
      return KindOfDouble;
    }
  }

  if (!allow_errors) {
    return KindOfNull;
  }
  if (allow_errors == -1) {
    raise_notice("A non well formed numeric value encountered");
  }

  if (allow_errors) {
    if (end_ptr_double > end_ptr_long && dval) {
      *dval = local_dval;
      return KindOfDouble;
    } else if (end_ptr_long && lval) {
      *lval = local_lval;
      return KindOfInt64;
    }
  }
  return KindOfNull;
}
Example #13
0
NEVER_INLINE
TypedValue arrayGetNotFound(const StringData* k) {
  raise_notice("Undefined index: %s", k->data());
  return make_tv<KindOfNull>();
}
Example #14
0
void raiseArrayIndexNotice(const int64_t index) {
  raise_notice("Undefined index: %" PRId64, index);
}
Example #15
0
TypedValue* ArrayData::nvGetNotFound(const StringData* k) {
  raise_notice("Undefined index: %s", k->data());
  return (TypedValue*)&init_null_variant;
}
Example #16
0
TypedValue* ArrayData::nvGetNotFound(int64 k) {
  raise_notice("Undefined index: %" PRId64, k);
  return (TypedValue*)&init_null_variant;
}
Example #17
0
CVarRef ArrayData::getNotFound(const StringData* k) {
  raise_notice("Undefined index: %s", k->data());
  return null_variant;
}
Example #18
0
CVarRef ArrayData::getNotFound(CStrRef k) {
  raise_notice("Undefined index: %s", k.data());
  return null_variant;
}
Example #19
0
CVarRef ArrayData::getNotFound(litstr k) {
  raise_notice("Undefined index: %s", k);
  return null_variant;
}
Example #20
0
CVarRef ArrayData::getNotFound(int64 k) {
  raise_notice("Undefined index: %lld", k);
  return null_variant;
}
Example #21
0
StringData* tvCastToString(const TypedValue* tv) {
  assert(tvIsPlausible(*tv));
  if (tv->m_type == KindOfRef) {
    tv = tv->m_data.pref->tv();
  }

  switch (tv->m_type) {
    case KindOfUninit:
    case KindOfNull:
      return staticEmptyString();

    case KindOfBoolean:
      return tv->m_data.num ? s_1.get() : staticEmptyString();

    case KindOfInt64:
      return buildStringData(tv->m_data.num);

    case KindOfDouble:
      return buildStringData(tv->m_data.dbl);

    case KindOfPersistentString:
      return tv->m_data.pstr;

    case KindOfString: {
      auto s = tv->m_data.pstr;
      s->incRefCount();
      return s;
    }

    case KindOfPersistentVec:
    case KindOfVec:
      raise_notice("Vec to string conversion");
      return vec_string.get();

    case KindOfPersistentDict:
    case KindOfDict:
      raise_notice("Dict to string conversion");
      return dict_string.get();

    case KindOfPersistentKeyset:
    case KindOfKeyset:
      raise_notice("Keyset to string conversion");
      return keyset_string.get();

    case KindOfPersistentArray:
    case KindOfArray:
      raise_notice("Array to string conversion");
      return array_string.get();

    case KindOfObject:
      return tv->m_data.pobj->invokeToString().detach();

    case KindOfResource:
      return tv->m_data.pres->data()->o_toString().detach();

    case KindOfRef:
    case KindOfClass:
      not_reached();
  }
  not_reached();
}
Example #22
0
void raiseArrayKeyNotice(const StringData* key) {
  raise_notice("Undefined key: %s", key->data());
}
Example #23
0
void raiseNotice(const StringData* sd) {
  raise_notice("%s", sd->data());
}
Example #24
0
void tvCastToStringInPlace(TypedValue* tv) {
  assert(tvIsPlausible(*tv));
  tvUnboxIfNeeded(tv);

  auto string = [&](StringData* s) {
    tv->m_type = KindOfString;
    tv->m_data.pstr = s;
  };
  auto persistentString = [&](StringData* s) {
    assert(!s->isRefCounted());
    tv->m_type = KindOfPersistentString;
    tv->m_data.pstr = s;
  };

  switch (tv->m_type) {
    case KindOfUninit:
    case KindOfNull:
      return persistentString(staticEmptyString());

    case KindOfBoolean:
      return persistentString(tv->m_data.num ? s_1.get() : staticEmptyString());

    case KindOfInt64:
      return string(buildStringData(tv->m_data.num));

    case KindOfDouble:
      return string(buildStringData(tv->m_data.dbl));

    case KindOfPersistentString:
    case KindOfString:
      return;

    case KindOfVec:
    case KindOfPersistentVec:
      raise_notice("Vec to string conversion");
      if (tv->m_type == KindOfVec) tvDecRefArr(tv);
      return persistentString(vec_string.get());

    case KindOfDict:
    case KindOfPersistentDict:
      raise_notice("Dict to string conversion");
      if (tv->m_type == KindOfDict) tvDecRefArr(tv);
      return persistentString(dict_string.get());

    case KindOfKeyset:
    case KindOfPersistentKeyset:
      raise_notice("Keyset to string conversion");
      if (tv->m_type == KindOfKeyset) tvDecRefArr(tv);
      return persistentString(keyset_string.get());

    case KindOfArray:
    case KindOfPersistentArray:
      raise_notice("Array to string conversion");
      if (tv->m_type == KindOfArray) tvDecRefArr(tv);
      return persistentString(array_string.get());

    case KindOfObject:
      // For objects, we fall back on the Variant machinery
      tvAsVariant(tv) = tv->m_data.pobj->invokeToString();
      return;

    case KindOfResource:
      // For resources, we fall back on the Variant machinery
      tvAsVariant(tv) = tv->m_data.pres->data()->o_toString();
      return;

    case KindOfRef:
    case KindOfClass:
      break;
  }
  not_reached();
}
Example #25
0
NEVER_INLINE
TypedValue arrayGetNotFound(int64_t k) {
  raise_notice("Undefined index: %" PRId64, k);
  return make_tv<KindOfNull>();
}
Example #26
0
const Variant& ArrayData::getNotFound(const Variant& k) {
  raise_notice("Undefined index: %s", k.toString().data());
  return null_variant;
}
Example #27
0
void NEVER_INLINE raise_null_object_prop() {
  raise_notice("Trying to get property of non-object");
}
Example #28
0
void TypeConstraint::verifyFail(const Func* func, TypedValue* tv,
                                int id, bool useStrictTypes) const {
  VMRegAnchor _;
  std::string name = displayName(func);
  auto const givenType = describe_actual_type(tv, isHHType());

  if (UNLIKELY(!useStrictTypes)) {
    if (auto dt = underlyingDataType()) {
      // In non-strict mode we may be able to coerce a type failure. For object
      // typehints there is no possible coercion in the failure case, but HNI
      // builtins currently only guard on kind not class so the following wil
      // generate false positives for objects.
      if (*dt != KindOfObject) {
        // HNI conversions implicitly unbox references, this behavior is wrong,
        // in particular it breaks the way type conversion works for PHP 7
        // scalar type hints
        if (tv->m_type == KindOfRef) {
          auto inner = tv->m_data.pref->var()->asTypedValue();
          if (tvCoerceParamInPlace(inner, *dt)) {
            tvAsVariant(tv) = tvAsVariant(inner);
            return;
          }
        } else {
          if (tvCoerceParamInPlace(tv, *dt)) return;
        }
      }
    }
  } else if (UNLIKELY(!func->unit()->isHHFile() &&
                      !RuntimeOption::EnableHipHopSyntax)) {
    // PHP 7 allows for a widening conversion from Int to Float. We still ban
    // this in HH files.
    if (auto dt = underlyingDataType()) {
      if (*dt == KindOfDouble && tv->m_type == KindOfInt64 &&
          tvCoerceParamToDoubleInPlace(tv)) {
        return;
      }
    }
  }

  // Handle return type constraint failures
  if (id == ReturnId) {
    std::string msg;
    if (func->isClosureBody()) {
      msg =
        folly::format(
          "Value returned from {}closure must be of type {}, {} given",
          func->isAsync() ? "async " : "",
          name,
          givenType
        ).str();
    } else {
      msg =
        folly::format(
          "Value returned from {}{} {}() must be of type {}, {} given",
          func->isAsync() ? "async " : "",
          func->preClass() ? "method" : "function",
          func->fullName(),
          name,
          givenType
        ).str();
    }
    if (RuntimeOption::EvalCheckReturnTypeHints >= 2 && !isSoft()) {
      raise_return_typehint_error(msg);
    } else {
      raise_warning_unsampled(msg);
    }
    return;
  }

  // Handle implicit collection->array conversion for array parameter type
  // constraints
  auto c = tvToCell(tv);
  if (isArray() && !isSoft() && !func->mustBeRef(id) &&
      c->m_type == KindOfObject && c->m_data.pobj->isCollection()) {
    // To ease migration, the 'array' type constraint will implicitly cast
    // collections to arrays, provided the type constraint is not soft and
    // the parameter is not by reference. We raise a notice to let the user
    // know that there was a type mismatch and that an implicit conversion
    // was performed.
    raise_notice(
      folly::format(
        "Argument {} to {}() must be of type {}, {} given; argument {} was "
        "implicitly cast to array",
        id + 1, func->fullName(), name, givenType, id + 1
      ).str()
    );
    tvCastToArrayInPlace(tv);
    return;
  }

  // Handle parameter type constraint failures
  if (isExtended() && isSoft()) {
    // Soft extended type hints raise warnings instead of recoverable
    // errors, to ease migration.
    raise_warning_unsampled(
      folly::format(
        "Argument {} to {}() must be of type {}, {} given",
        id + 1, func->fullName(), name, givenType
      ).str()
    );
  } else if (isExtended() && isNullable()) {
    raise_typehint_error(
      folly::format(
        "Argument {} to {}() must be of type {}, {} given",
        id + 1, func->fullName(), name, givenType
      ).str()
    );
  } else {
    auto cls = Unit::lookupClass(m_typeName);
    if (cls && isInterface(cls)) {
      raise_typehint_error(
        folly::format(
          "Argument {} passed to {}() must implement interface {}, {} given",
          id + 1, func->fullName(), name, givenType
        ).str()
      );
    } else {
      raise_typehint_error(
        folly::format(
          "Argument {} passed to {}() must be an instance of {}, {} given",
          id + 1, func->fullName(), name, givenType
        ).str()
      );
    }
  }
}
Example #29
0
const Variant& ArrayData::getNotFound(int64_t k) {
  raise_notice("Undefined index: %" PRId64, k);
  return null_variant;
}
Example #30
0
void raiseArrayIndexNotice(const int64_t index, bool isInOut) {
  raise_notice("Undefined index%s: %" PRId64,
               isInOut ? " on inout parameter" : "", index);
}