std::string Path::normalize(const std::string & path) { // Easiest way is: split, then remove "." and remove a/.. (but not ../.. !) // This does not get a/b/../.. so if we remove a/.., go through the string again // Also need to treat rootdir/.. specially // Also normalize(foo/..) -> "." but normalize(foo/bar/..) -> "foo" StringVec v = Path::split(path); if (v.size() == 0) return ""; StringVec outv; bool doAgain = true; while (doAgain) { doAgain = false; for (unsigned int i = 0; i < v.size(); i++) { if (v[i] == "") continue; // remove empty fields if (v[i] == "." && v.size() > 1) continue; // skip "." unless it is by itself if (i == 0 && isRootdir(v[i]) && i+1 < v.size() && v[i+1] == "..") { // <root>/.. -> <root> outv.push_back(v[i]); i++; // skipped following ".." doAgain = true; continue; } // remove "foo/.." if (i+1 < v.size() && v[i] != ".." && v[i+1] == "..") { // but as a special case, if the full path is "foo/.." return "." if (v.size() == 2) return "."; i++; doAgain = true; continue; } outv.push_back(v[i]); } if (doAgain) { v = outv; outv.clear(); } } return Path::join(outv.begin(), outv.end()); }
//--------------------------------------------------------------------------------------------------------------------- // This is basically like the Perl split() function. It splits str into substrings by cutting it at each delimiter. // The result is stored in vec. //--------------------------------------------------------------------------------------------------------------------- void Split(const string& str, StringVec& vec, char delimiter) { vec.clear(); size_t strLen = str.size(); if (strLen == 0) return; size_t startIndex = 0; size_t indexOfDel = str.find_first_of(delimiter, startIndex); while (indexOfDel != string::npos) { vec.push_back(str.substr(startIndex, indexOfDel-startIndex)); startIndex=indexOfDel + 1; if (startIndex >= strLen) break; indexOfDel = str.find_first_of(delimiter, startIndex); } if(startIndex < strLen) vec.push_back(str.substr(startIndex)); }
Variant c_DebuggerClient::t_processcmd(CVarRef cmdName, CVarRef args) { INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClient, DebuggerClient::processcmd); if (!m_client || m_client->getClientState() < DebuggerClient::StateReadyForCommand) { raise_warning("client is not initialized"); return null; } if (m_client->getClientState() != DebuggerClient::StateReadyForCommand) { raise_warning("client is not ready to take command"); return null; } if (!cmdName.isString()) { raise_warning("cmdName must be string"); return null; } if (!args.isNull() && !args.isArray()) { raise_warning("args must be null or array"); return null; } static const char *s_allowedCmds[] = { "break", "continue", "down", "exception", "frame", "global", "help", "info", "konstant", "next", "out", "print", "quit", "step", "up", "variable", "where", "bt", "set", "inst", "=", "@", NULL }; bool allowed = false; for (int i = 0; ; i++) { const char *cmd = s_allowedCmds[i]; if (cmd == NULL) { break; } if (cmdName.same(cmd)) { allowed = true; break; } } if (!allowed) { raise_warning("unsupported command %s", cmdName.toString().data()); return null; } m_client->setCommand(cmdName.toString().data()); StringVec *clientArgs = m_client->args(); clientArgs->clear(); if (!args.isNull()) { for (ArrayIter iter(args.toArray()); iter; ++iter) { CStrRef arg = iter.second().toString(); clientArgs->push_back(std::string(arg.data(), arg.size())); } } try { if (!m_client->process()) { raise_warning("command \"%s\" not found", cmdName.toString().data()); } } catch (DebuggerConsoleExitException &e) { // Flow-control command goes here Logger::Info("wait for debugger client to stop"); m_client->setTakingInterrupt(); m_client->setClientState(DebuggerClient::StateBusy); DebuggerCommandPtr cmd = m_client->waitForNextInterrupt(); if (!cmd) { raise_warning("not getting a command"); } else if (cmd->is(DebuggerCommand::KindOfInterrupt)) { CmdInterruptPtr cmdInterrupt = dynamic_pointer_cast<CmdInterrupt>(cmd); cmdInterrupt->onClientD(m_client); } else { // Previous pending commands cmd->handleReply(m_client); cmd->setClientOutput(m_client); } Logger::Info("debugger client ready for command"); } catch (DebuggerClientExitException &e) { const std::string& nameStr = m_client->getNameApi(); Logger::Info("client %s disconnected", nameStr.c_str()); s_dbgCltMap.erase(nameStr); delete m_client; m_client = NULL; return true; } catch (DebuggerProtocolException &e) { raise_warning("DebuggerProtocolException"); return null; } return m_client->getOutputArray(); }
/**************************************************************************** ** ** Author: Marc Bowes ** Author: Tim Sjoberg ** ** Extracts variable information from the login packet ** FIXME: Poll data looks fishy ** ****************************************************************************/ VariableHash Login::handle(const QByteArray &packet) { /* == PACKET FORMAT *************************************************************************** ** ** 1\0 ** errorCode[\1errorMessage]\0 ** sesid\0 ** deprecated\1loginname\1dateTime\1URL\1 ** maxSupportedVer\1pricePlan\1flags ** [\0Poll data] ** *************************************************************************** == DEFINITIONS *************************************************************************** ** ** sesid the session ID (>1 for HTTP connections and 0 for ** TCP connections) ** deprecated deprecated functionality (expect an empty string) ** loginname the user's loginname ** dateTime the date and time in number of seconds since ** 1 January 1970 (UTC) ** URL is the URL of the proxy handling your current ** session. Use this URL to reconnect to if ** disconnected. ** maxSupportedVer maximum protocol version supported by the server ** (major*10+minor) ** pricePlan the price plan the user is on: ** 1 - free ** 2 - premium ** flags contains specific flags for this user. At the ** moment only indicates if session is encrypted or not. ** poll data if getContacts was set to 1, this will contain the ** user's contacts as well as their presence information ** and all new messages; ** *************************************************************************** == ERRORS *************************************************************************** ** ** 3 Invalid password ** 16 Redirect[1] to new proxy ** 99 Something went wrong ** *************************************************************************** == NOTES *************************************************************************** ** ** [1] Redirect ** The client is requested to redirect to the URL specified in the ** errorMessage field. The URL will be in the following format: ** protocol://host:port;type[;msg] ** *************************************************************************** */ /* setup */ StringVec variables; /* first break up packet by \0 into variable sections */ variables.append("sesid"); /* sesid\0 */ variables.append("data"); /* deprecated..flags\0 */ /* extract \0 seperated values */ VariableHash pass1 = hashVariables(packet, variables, '\0'); /* need to expand data section */ variables.clear(); variables.append("deprecated"); variables.append("loginname"); variables.append("dateTime"); variables.append("URL"); variables.append("maxSuppertedVer"); variables.append("pricePlan"); variables.append("flags"); /* extract \1 seperated values */ VariableHash pass2 = hashVariables(pass1["data"], variables, '\1'); /* no clean-up needed, just return the variables */ return pass1.unite(pass2); }
StringTable() { m_map.clear(); m_vec.clear(); m_invalid = "invalid-string"; }
/**************************************************************************** ** ** Author: Tim Sjoberg ** ** Extracts variable information from the register packet ** ****************************************************************************/ VariableHash Register::handle(const QByteArray &packet) { /* == PACKET FORMAT *************************************************************************** ** ** 11 \0 ** errorCode [ \1 errorMessage ] \0 ** sesid \0 ** deprecated \1 loginname \1 timeStamp \1 serverIP \1 maxSupportedVer \1 pricePlan \1 ** flags \0 ** hiddenLoginname ** [ \0 Poll data ] ** *************************************************************************** == DEFINITIONS *************************************************************************** ** ** errorCode see 1. Login ** deprecated deprecated functionality (expect an empty string) ** loginname is the user's loginname ** timeStamp the number of seconds since 1 January 1970 (UTC) ** serverIP the IP address of the server ** maxSupportedVer maximum protocol version supported by the server ** (major*10+minor) ** pricePlan the price plan the user is on: ** 1 - free ** 2 - premium ** flags specific flags for this user ** hiddenLoginname specifies whether the user's loginname should be ** hidden when inviting a contact: ** 0 - not hidden ** 1 - hidden ** poll data this will contain the user's contacts as well as ** their presence information and all new messages. ** *************************************************************************** */ StringVec variables; /* first break up packet by \0 into variable sections */ variables.append("sesid"); /* sesid\0 */ variables.append("data"); /* deprecated..flags\0 */ variables.append("hiddenLoginname"); /* extract \0 seperated values */ VariableHash pass1 = hashVariables(packet, variables, '\0'); /* need to expand data section */ variables.clear(); variables.append("deprecated"); variables.append("loginname"); variables.append("dateTime"); variables.append("URL"); variables.append("maxSuppertedVer"); variables.append("pricePlan"); variables.append("flags"); /* extract \1 seperated values */ VariableHash pass2 = hashVariables(pass1["data"], variables, '\1'); /* no clean-up needed, just return the variables */ return pass1.unite(pass2); return VariableHash(); }
bool Store::loadFromXml(bool /*reloading = false*/) { pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file("data/store/store.xml"); if (!result) { printXMLError("Error - Store::loadFromXml", "data/store/store.xml", result); return false; } loaded = true; std::string name; std::string description; StringVec icons; for (auto categoryNode : doc.child("store").children()) { pugi::xml_attribute attr; name.clear(); description.clear(); icons.clear(); if ((attr = categoryNode.attribute("name"))) { name = attr.as_string(); } else { std::cout << "[Error - Store::loadFromXml] Missing category name." << std::endl; continue; } if ((attr = categoryNode.attribute("description"))) { description = attr.as_string(); } if ((attr = categoryNode.attribute("icons"))) { icons = explodeString(attr.as_string(), ";"); } categories.emplace_back(name, description, icons); StoreCategory& category = categories.back(); for (auto offerNode : categoryNode.children()) { StoreOffer& offer = category.createOffer(runningId++); if ((attr = offerNode.attribute("name"))) { offer.name = attr.as_string(); } else { std::cout << "[Error - Store::loadFromXml] Missing offer name in category: " << category.name << std::endl; category.offers.pop_back(); continue; } if ((attr = offerNode.attribute("description"))) { offer.description = attr.as_string(); } if ((attr = offerNode.attribute("message"))) { offer.message = attr.as_string(); } if ((attr = offerNode.attribute("icons"))) { offer.icons = explodeString(attr.as_string(), ";"); } if ((attr = offerNode.attribute("price"))) { offer.price = attr.as_uint(); } for (auto subOfferNode : offerNode.children()) { name.clear(); description.clear(); icons.clear(); if ((attr = subOfferNode.attribute("name"))) { name = attr.as_string(); } if ((attr = subOfferNode.attribute("description"))) { description = attr.as_string(); } if ((attr = subOfferNode.attribute("icons"))) { icons = explodeString(attr.as_string(), ";"); } offer.subOffers.push_back(SubOffer(name, description, icons)); } if ((attr = offerNode.attribute("script"))) { if (!scriptInterface) { scriptInterface.reset(new LuaScriptInterface("Store Interface")); scriptInterface->initState(); } std::string script = attr.as_string(); if (scriptInterface->loadFile("data/store/scripts/" + script) == 0) { offer.scriptInterface = scriptInterface.get(); offer.renderEvent = scriptInterface->getEvent("onRender"); offer.buyEvent = scriptInterface->getEvent("onBuy"); } else { std::cout << "[Warning - Store::loadFromXml] Can not load script: " << script << std::endl; std::cout << scriptInterface->getLastLuaError() << std::endl; } } } } return true; }