diff options
author | Peter Powell <petpow@saberuk.com> | 2014-03-26 20:02:49 +0000 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2014-04-11 15:50:01 +0200 |
commit | 12df291dc76879e79bfa94f788e7f8a4ce2455df (patch) | |
tree | ccef0932c49f6e254b7612fc2a7cf26d71d1aa6b | |
parent | 72a6b6077644abbdad1a61acbbd07bd01ba1b9bd (diff) |
Implement support for numeric character references.
-rw-r--r-- | src/configparser.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/src/configparser.cpp b/src/configparser.cpp index 92f05edd4..2f3fbb5b4 100644 --- a/src/configparser.cpp +++ b/src/configparser.cpp @@ -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 + { + 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); + } } else if (ch == '\\' && (flags & FLAG_USE_COMPAT)) { |