Exemplo n.º 1
0
void IniSetting::ParserCallback::traverseToSet(const String &key,
                                               const std::string& offset,
                                               Variant& value,
                                               Variant& cur_settings,
                                               const std::string& stopChar) {
  assert(stopChar == "@" || stopChar == ":");
  assert(offset != stopChar);
  assert(cur_settings.isArray());
  auto isSymlink = stopChar == ":";
  auto start = offset.c_str();
  auto p = start;
  auto& first(cur_settings.toArrRef().lvalAt(key));
  forceToArray(first);
  Variant *setting = &first;
  String index;
  bool done = false;
  while (!done) {
    index = String(p);
    p += index.size() + 1;
    if (strcmp(p, stopChar.c_str()) != 0) {
      forceToArray(*setting);
      setting = &setting->toArrRef().lvalAt(index);
    } else {
      done = true;
    }
  }
  if (isSymlink) {
    setting->toArrRef().setRef(index, value);
  } else {
    setting->toArrRef().set(index, value);
  }
}
Exemplo n.º 2
0
void IniSetting::ParserCallback::onPopEntry(
    const std::string &key,
    const std::string &value,
    const std::string &offset,
    void *arg) {
  Variant *arr = (Variant*)arg;
  forceToArray(*arr);

  bool oEmpty = offset.empty();
  // Substitution copy or symlink
  // Offset come in like: hhvm.a.b\0c\0@
  // Check for `\0` because it is possible, although unlikely, to have
  // something like hhvm.a.b[c@]. Thus we wouldn't want to make a substitution.
  if (!oEmpty && (offset.size() == 1 || offset[offset.size() - 2] == '\0') &&
      (offset.back() == '@' || offset.back() == ':')) {
    makeSettingSub(key, offset, value, *arr);
  } else {                                 // Normal array value
    String skey(key);
    auto& hash = arr->toArrRef().lvalAt(skey);
    forceToArray(hash);
    if (!oEmpty) {                         // a[b]
      makeArray(hash, offset, value);
    } else {                               // a[]
      hash.toArrRef().append(value);
    }
  }
}
Exemplo n.º 3
0
static void _xml_add_to_info(XmlParser *parser, const String& nameStr) {
  if (parser->info.isNull()) {
    return;
  }
  forceToArray(parser->info);
  if (!parser->info.toCArrRef().exists(nameStr)) {
    parser->info.toArrRef().set(nameStr, Array::Create());
  }
  auto& inner = parser->info.toArrRef().lvalAt(nameStr);
  forceToArray(inner).append(parser->curtag);
  parser->curtag++;
}
Exemplo n.º 4
0
void IniSetting::ParserCallback::onPopEntry(
    const std::string &key,
    const std::string &value,
    const std::string &offset,
    void *arg) {
  Variant *arr = (Variant*)arg;
  forceToArray(*arr);
  auto& hash = arr->toArrRef().lvalAt(String(key));
  forceToArray(hash);
  if (!offset.empty()) {
    makeArray(hash, offset, value);
  } else {
    hash.toArrRef().append(value);
  }
}
Exemplo n.º 5
0
void ExecutionContext::registerShutdownFunction(const Variant& function,
                                                Array arguments,
                                                ShutdownType type) {
  Array callback = make_map_array(s_name, function, s_args, arguments);
  Variant& funcs = m_shutdowns.lvalAt(type);
  forceToArray(funcs).append(callback);
}
Exemplo n.º 6
0
void IniSetting::ParserCallback::makeArray(Variant& hash,
                                           const std::string& offset,
                                           const std::string& value) {
  assert(!offset.empty());
  Variant *val = &hash;
  assert(val->isArray());
  auto start = offset.c_str();
  auto p = start;
  bool last = false;
  do {
    String index(p);
    last = p + index.size() >= start + offset.size();
    // This is mandatory in case we have a nested array like:
    //   hhvm.a[b][c][d]
    // b will be hash and an array already, but c and d might
    // not exist and will need to be made an array
    forceToArray(*val);
    val = &val->toArrRef().lvalAt(index);
    if (last) {
      *val = Variant(value);
    } else {
      p += index.size() + 1;
    }
  } while (!last);
}
Exemplo n.º 7
0
void IniSetting::ParserCallback::onEntry(
    const std::string &key, const std::string &value, void *arg) {
  Variant *arr = (Variant*)arg;
  String skey(key);
  Variant sval(value);
  forceToArray(*arr).set(skey, sval);
}
Exemplo n.º 8
0
bool ExecutionContext::removeShutdownFunction(const Variant& function,
                                              ShutdownType type) {
  bool ret = false;
  auto& funcs = forceToArray(m_shutdowns.lvalAt(type));
  PackedArrayInit newFuncs(funcs.size());

  for (ArrayIter iter(funcs); iter; ++iter) {
    if (!same(iter.second().toArray()[s_name], function)) {
      newFuncs.appendWithRef(iter.secondRef());
    } else {
      ret = true;
    }
  }
  funcs = newFuncs.toArray();
  return ret;
}
Exemplo n.º 9
0
Array TimeZone::GetAbbreviations() {
  Array ret;
  for (const timelib_tz_lookup_table *entry =
         timelib_timezone_abbreviations_list(); entry->name; entry++) {
    ArrayInit element(3, ArrayInit::Map{});
    element.set(s_dst, (bool)entry->type);
    element.set(s_offset, entry->gmtoffset);
    if (entry->full_tz_name) {
      element.set(s_timezone_id, String(entry->full_tz_name, CopyString));
    } else {
      element.set(s_timezone_id, uninit_null());
    }
    auto& val = ret.lvalAt(String(entry->name));
    forceToArray(val).append(element.toArray());
  }
  return ret;
}
Exemplo n.º 10
0
Variant json_type_object_to_variant(json_object *new_obj, const bool assoc,
                                    const bool stable_maps,
                                    const bool collections) {
    struct json_object_iterator it, itEnd;
    json_object  *jobj;
    Variant       var, tmpvar;

  if (collections) {
    var = newobj<c_Map>();
  } else if (assoc) {
    var = Array::Create();
  } else {
    var = SystemLib::AllocStdClassObject();
  }

  it = json_object_iter_begin(new_obj);
  itEnd = json_object_iter_end(new_obj);

  while (!json_object_iter_equal(&it, &itEnd)) {
    String key(json_object_iter_peek_name(&it), CopyString);
    jobj = json_object_iter_peek_value(&it);
    tmpvar = json_object_to_variant(jobj, assoc, stable_maps, collections);

    if (!assoc) {
      if (key.empty()) {
        var.getObjectData()->o_set(s_empty, tmpvar);
      } else {
        var.getObjectData()->o_set(key, tmpvar);
      }
    } else {
      if (collections) {
        auto keyTV = make_tv<KindOfString>(key.get());
        collectionSet(var.getObjectData(), &keyTV, tmpvar.asCell());
      } else {
        forceToArray(var).set(key, tmpvar);
      }
    }
    json_object_iter_next(&it);
  }
  return var;
}
Exemplo n.º 11
0
void DummySandbox::run() {
  TRACE(2, "DummySandbox::run\n");
  RequestInfo *ti = RequestInfo::s_requestInfo.getNoCheck();
  while (!m_stopped) {
    try {
      CLISession hphpSession;

      DSandboxInfo sandbox = m_proxy->getSandbox();
      std::string msg;
      if (sandbox.valid()) {
        SourceRootInfo sri(sandbox.m_user, sandbox.m_name);
        if (sandbox.m_path.empty()) {
          sandbox.m_path = sri.path();
        }
        if (!sri.sandboxOn()) {
          msg = "Invalid sandbox was specified. "
            "PHP files may not be loaded properly.\n";
        } else {
          auto server = php_global_exchange(s__SERVER, init_null());
          forceToArray(server);
          Array arr = server.toArrRef();
          server.unset();
          php_global_set(s__SERVER, sri.setServerVariables(std::move(arr)));
        }
        Debugger::RegisterSandbox(sandbox);
        g_context->setSandboxId(sandbox.id());

        std::string doc = getStartupDoc(sandbox);
        if (!doc.empty()) {
          char cwd[PATH_MAX];
          getcwd(cwd, sizeof(cwd));
          Logger::Info("Start loading startup doc '%s', pwd = '%s'",
                       doc.c_str(), cwd);
          bool error; std::string errorMsg;
          bool ret = hphp_invoke(g_context.getNoCheck(), doc, false, null_array,
                                 uninit_null(), "", "", error, errorMsg, true,
                                 false, true, RuntimeOption::EvalPreludePath);
          if (!ret || error) {
            msg += "Unable to pre-load " + doc;
            if (!errorMsg.empty()) {
              msg += ": " + errorMsg;
            }
          }
          Logger::Info("Startup doc " + doc + " loaded");
        }
      } else {
        g_context->setSandboxId(m_proxy->getDummyInfo().id());
      }

      if (!DebuggerHook::attach<HphpdHook>(ti)) {
        const char* fail = "Could not attach hphpd to request: another debugger"
                           " is already attached.";
        Logger::Error("%s", fail);
        Debugger::InterruptSessionStarted(nullptr, fail);
        throw DebuggerClientAttachFailureException();
      }
      {
        DebuggerDummyEnv dde;
        // This is really the entire point of having the dummy sandbox. This
        // fires the initial session started interrupt to the client after
        // it first attaches.
        Debugger::InterruptSessionStarted(nullptr, msg.c_str());
      }

      // Blocking until Ctrl-C is issued by end user and DebuggerProxy cannot
      // find a real sandbox thread to handle it.
      {
        Lock lock(this);
        while (!m_stopped && m_signum != CmdSignal::SignalBreak) {
          wait(1);
        }
        if (m_stopped) {
          // stopped by worker thread
          break;
        }
        m_signum = CmdSignal::SignalNone;
      }
    } catch (const DebuggerClientExitException& e) {
      // stopped by the dummy sandbox thread itself
      break;
    } catch (const DebuggerException& e) {
    }
  }
}
Exemplo n.º 12
0
void IniSetting::ParserCallback::onEntry(
    const std::string &key, const std::string &value, void *arg) {
  Variant *arr = (Variant*)arg;
  forceToArray(*arr).set(String(key), Variant(value));
}
Exemplo n.º 13
0
void DummySandbox::run() {
  TRACE(2, "DummySandbox::run\n");
  ThreadInfo *ti = ThreadInfo::s_threadInfo.getNoCheck();
  while (!m_stopped) {
    try {
      CLISession hphpSession;

      DSandboxInfo sandbox = m_proxy->getSandbox();
      std::string msg;
      if (sandbox.valid()) {
        GlobalVariables *g = get_global_variables();
        SourceRootInfo sri(sandbox.m_user, sandbox.m_name);
        if (sandbox.m_path.empty()) {
          sandbox.m_path = sri.path();
        }
        if (!sri.sandboxOn()) {
          msg = "Invalid sandbox was specified. "
            "PHP files may not be loaded properly.\n";
        } else {
          auto& server = tvAsVariant(g->nvGet(s__SERVER.get()));
          forceToArray(server);
          sri.setServerVariables(server.toArrRef());
        }
        Debugger::RegisterSandbox(sandbox);
        g_context->setSandboxId(sandbox.id());

        std::string doc = getStartupDoc(sandbox);
        if (!doc.empty()) {
          char cwd[PATH_MAX];
          getcwd(cwd, sizeof(cwd));
          Logger::Info("Start loading startup doc '%s', pwd = '%s'",
                       doc.c_str(), cwd);
          bool error; std::string errorMsg;
          bool ret = hphp_invoke(g_context.getNoCheck(), doc, false, null_array,
                                 uninit_null(), "", "", error, errorMsg, true,
                                 false, true);
          if (!ret || error) {
            msg += "Unable to pre-load " + doc;
            if (!errorMsg.empty()) {
              msg += ": " + errorMsg;
            }
          }
          Logger::Info("Startup doc " + doc + " loaded");
        }
      } else {
        g_context->setSandboxId(m_proxy->getDummyInfo().id());
      }

      ti->m_reqInjectionData.setDebugger(true);
      {
        DebuggerDummyEnv dde;
        // This is really the entire point of having the dummy sandbox. This
        // fires the initial session started interrupt to the client after
        // it first attaches.
        Debugger::InterruptSessionStarted(nullptr, msg.c_str());
      }

      // Blocking until Ctrl-C is issued by end user and DebuggerProxy cannot
      // find a real sandbox thread to handle it.
      {
        Lock lock(this);
        while (!m_stopped && m_signum != CmdSignal::SignalBreak) {
          wait(1);
        }
        if (m_stopped) {
          // stopped by worker thread
          break;
        }
        m_signum = CmdSignal::SignalNone;
      }
    } catch (const DebuggerClientExitException &e) {
      // stopped by the dummy sandbox thread itself
      break;
    } catch (const DebuggerException &e) {
    }
  }
}