]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/configparser.cpp
Keep multiple IOHookProvider references in class ListenSocket
[user/henk/code/inspircd.git] / src / configparser.cpp
index 0e2a8670631d836126a56baeaa6987e303efb6ac..3be1ac9c53d39ce44f0a79dcd6d81defa55735f9 100644 (file)
@@ -125,7 +125,7 @@ struct Parser
                                while (1)
                                {
                                        ch = next();
-                                       if (isalnum(ch))
+                                       if (isalnum(ch) || (varname.empty() && ch == '#'))
                                                varname.push_back(ch);
                                        else if (ch == ';')
                                                break;
@@ -136,10 +136,30 @@ struct Parser
                                                throw CoreException("Parse error");
                                        }
                                }
-                               std::map<std::string, std::string>::iterator var = stack.vars.find(varname);
-                               if (var == stack.vars.end())
-                                       throw CoreException("Undefined XML entity reference '&" + varname + ";'");
-                               value.append(var->second);
+                               if (varname.empty())
+                                       throw CoreException("Empty XML entity reference");
+                               else if (varname[0] == '#' && (varname.size() == 1 || (varname.size() == 2 && varname[1] == 'x')))
+                                       throw CoreException("Empty numeric character reference");
+                               else if (varname[0] == '#')
+                               {
+                                       const char* cvarname = varname.c_str();
+                                       char* endptr;
+                                       unsigned long lvalue;
+                                       if (cvarname[1] == 'x')
+                                               lvalue = strtoul(cvarname + 2, &endptr, 16);
+                                       else
+                                               lvalue = strtoul(cvarname + 1, &endptr, 10);
+                                       if (*endptr != '\0' || lvalue > 255)
+                                               throw CoreException("Invalid numeric character reference '&" + varname + ";'");
+                                       value.push_back(static_cast<char>(lvalue));
+                               }
+                               else
+                               {
+                                       insp::flat_map<std::string, std::string>::iterator var = stack.vars.find(varname);
+                                       if (var == stack.vars.end())
+                                               throw CoreException("Undefined XML entity reference '&" + varname + ";'");
+                                       value.append(var->second);
+                               }
                        }
                        else if (ch == '\\' && (flags & FLAG_USE_COMPAT))
                        {
@@ -300,7 +320,7 @@ void ParseStack::DoInclude(ConfigTag* tag, int flags)
                        flags |= FLAG_NO_INC;
                if (tag->getBool("noexec", false))
                        flags |= FLAG_NO_EXEC;
-               if (!ParseFile(name, flags, mandatorytag))
+               if (!ParseFile(ServerInstance->Config->Paths.PrependConfig(name), flags, mandatorytag))
                        throw CoreException("Included");
        }
        else if (tag->readString("executable", name))
@@ -311,7 +331,7 @@ void ParseStack::DoInclude(ConfigTag* tag, int flags)
                        flags |= FLAG_NO_INC;
                if (tag->getBool("noexec", true))
                        flags |= FLAG_NO_EXEC;
-               if (!ParseExec(name, flags, mandatorytag))
+               if (!ParseFile(name, flags, mandatorytag, true))
                        throw CoreException("Included");
        }
 }
@@ -344,21 +364,15 @@ void ParseStack::DoReadFile(const std::string& key, const std::string& name, int
        }
 }
 
-bool ParseStack::ParseFile(const std::string& name, int flags, const std::string& mandatory_tag)
+bool ParseStack::ParseFile(const std::string& path, int flags, const std::string& mandatory_tag, bool isexec)
 {
-       std::string path = ServerInstance->Config->Paths.PrependConfig(name);
-       ServerInstance->Logs->Log("CONFIG", LOG_DEBUG, "Reading file %s", path.c_str());
-       for (unsigned int t = 0; t < reading.size(); t++)
-       {
-               if (std::string(name) == reading[t])
-               {
-                       throw CoreException("File " + path + " is included recursively (looped inclusion)");
-               }
-       }
+       ServerInstance->Logs->Log("CONFIG", LOG_DEBUG, "Reading (isexec=%d) %s", isexec, path.c_str());
+       if (stdalgo::isin(reading, path))
+               throw CoreException((isexec ? "Executable " : "File ") + path + " is included recursively (looped inclusion)");
 
        /* It's not already included, add it to the list of files we've loaded */
 
-       FileWrapper file(fopen(path.c_str(), "r"));
+       FileWrapper file((isexec ? popen(path.c_str(), "r") : fopen(path.c_str(), "r")), isexec);
        if (!file)
                throw CoreException("Could not read \"" + path + "\" for include");
 
@@ -369,34 +383,8 @@ bool ParseStack::ParseFile(const std::string& name, int flags, const std::string
        return ok;
 }
 
-bool ParseStack::ParseExec(const std::string& name, int flags, const std::string& mandatory_tag)
-{
-       ServerInstance->Logs->Log("CONFIG", LOG_DEBUG, "Reading executable %s", name.c_str());
-       for (unsigned int t = 0; t < reading.size(); t++)
-       {
-               if (std::string(name) == reading[t])
-               {
-                       throw CoreException("Executable " + name + " is included recursively (looped inclusion)");
-               }
-       }
-
-       /* It's not already included, add it to the list of files we've loaded */
-
-       FileWrapper file(popen(name.c_str(), "r"), true);
-       if (!file)
-               throw CoreException("Could not open executable \"" + name + "\" for include");
-
-       reading.push_back(name);
-       Parser p(*this, flags, file, name, mandatory_tag);
-       bool ok = p.outer_parse();
-       reading.pop_back();
-       return ok;
-}
-
 bool ConfigTag::readString(const std::string& key, std::string& value, bool allow_lf)
 {
-       if (!this)
-               return false;
        for(std::vector<KeyVal>::iterator j = items.begin(); j != items.end(); ++j)
        {
                if(j->first != key)
@@ -500,10 +488,10 @@ std::string ConfigTag::getTagLocation()
        return src_name + ":" + ConvToStr(src_line);
 }
 
-ConfigTag* ConfigTag::create(const std::string& Tag, const std::string& file, int line, std::vector<KeyVal>*&items)
+ConfigTag* ConfigTag::create(const std::string& Tag, const std::string& file, int line, std::vector<KeyVal>*& Items)
 {
        ConfigTag* rv = new ConfigTag(Tag, file, line);
-       items = &rv->items;
+       Items = &rv->items;
        return rv;
 }