diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/IceGrid/NodeCache.cpp | 22 | ||||
-rw-r--r-- | cpp/src/IceGrid/Util.cpp | 71 | ||||
-rwxr-xr-x | cpp/src/IceGrid/Util.h | 2 | ||||
-rw-r--r-- | cpp/test/IceGrid/deployer/AllTests.cpp | 16 | ||||
-rw-r--r-- | cpp/test/IceGrid/deployer/server.xml | 8 | ||||
-rw-r--r-- | cpp/test/IceGrid/deployer/service.xml | 10 |
6 files changed, 109 insertions, 20 deletions
diff --git a/cpp/src/IceGrid/NodeCache.cpp b/cpp/src/IceGrid/NodeCache.cpp index 584c88bae6e..19d9f5706fb 100644 --- a/cpp/src/IceGrid/NodeCache.cpp +++ b/cpp/src/IceGrid/NodeCache.cpp @@ -143,7 +143,7 @@ struct ToInternalServerDescriptor : std::unary_function<CommunicatorDescriptorPt { if(p->name.find('#') != 0 || !p->value.empty()) { - p->name = escapeProperty(p->name); + p->name = escapeProperty(p->name, true); p->value = escapeProperty(p->value); } } @@ -954,9 +954,23 @@ NodeEntry::getInternalServerDescriptor(const ServerInfo& info) const { ServiceDescriptorPtr s = p->descriptor; const string path = _session->getInfo()->dataDir + "/servers/" + server->id + "/config/config_" + s->name; - props.push_back(createProperty("IceBox.Service." + s->name, s->entry + " --Ice.Config='" + - escapeProperty(path) + "'")); - servicesStr += s->name + " "; + + // + // We escape the path here because the command-line option --Ice.Config=xxx will be parsed an encoded + // (escaped) property + // For example, \\server\dir\file.cfg needs to become \\\server\dir\file.cfg or \\\\server\\dir\\file.cfg. + // + props.push_back(createProperty("IceBox.Service." + s->name, s->entry + " --Ice.Config='" + + escapeProperty(path) + "'")); + + if(servicesStr.empty()) + { + servicesStr = s->name; + } + else + { + servicesStr += " " + s->name; + } } if(!hasProperty(info.descriptor->propertySet.properties, "IceBox.InstanceName")) { diff --git a/cpp/src/IceGrid/Util.cpp b/cpp/src/IceGrid/Util.cpp index 78c1c04aab0..3c22ce4f336 100644 --- a/cpp/src/IceGrid/Util.cpp +++ b/cpp/src/IceGrid/Util.cpp @@ -105,34 +105,77 @@ IceGrid::createProperty(const string& name, const string& value) } string -IceGrid::escapeProperty(const string& s) +IceGrid::escapeProperty(const string& s, bool escapeEqual) { size_t firstChar = s.find_first_not_of(' '); size_t lastChar = s.find_last_not_of(' '); string result; + bool previousCharIsEscape = false; + for(unsigned int i = 0; i < s.size(); ++i) { char c = s[i]; switch(c) { case ' ': - if(i < firstChar || i > lastChar) - { - result.push_back('\\'); - } - result.push_back(c); - break; - - case '\\': + { + // + // We only escape the space character when it's at the beginning + // or at the end of the string + // + if(i < firstChar || i > lastChar) + { + if(previousCharIsEscape) + { + result.push_back('\\'); // escape the previous char, by adding another escape. + } + + result.push_back('\\'); + } + result.push_back(c); + previousCharIsEscape = false; + break; + } + + case '\\': case '#': case '=': - result.push_back('\\'); - result.push_back(c); - break; + { + if(c == '=' && !escapeEqual) + { + previousCharIsEscape = false; + } + else + { + // + // We only escape the \ character when it is followed by a + // character that we escape, e.g. \# is encoded as \\\#, not \# + // and \\server is encoded as \\\server. + // + if(previousCharIsEscape) + { + result.push_back('\\'); // escape the previous char, by adding another escape. + } + if(c == '\\') + { + previousCharIsEscape = true; // deferring the potential escaping to the next loop + } + else + { + result.push_back('\\'); + previousCharIsEscape = false; + } + } + result.push_back(c); + break; + } default: - result.push_back(c); - break; + { + result.push_back(c); + previousCharIsEscape = false; + break; + } } } return result; diff --git a/cpp/src/IceGrid/Util.h b/cpp/src/IceGrid/Util.h index a0e0404248d..2545187ba01 100755 --- a/cpp/src/IceGrid/Util.h +++ b/cpp/src/IceGrid/Util.h @@ -41,7 +41,7 @@ std::string toString(const Ice::Exception&); std::string getProperty(const PropertyDescriptorSeq&, const std::string&, const std::string& = std::string()); bool hasProperty(const PropertyDescriptorSeq&, const std::string&); PropertyDescriptor createProperty(const std::string&, const std::string& = std::string()); -std::string escapeProperty(const std::string&); +std::string escapeProperty(const std::string&, bool = false); void setupThreadPool(const Ice::PropertiesPtr&, const std::string&, int, int = 0, bool = false); diff --git a/cpp/test/IceGrid/deployer/AllTests.cpp b/cpp/test/IceGrid/deployer/AllTests.cpp index d6de544e215..4a13ea3df9a 100644 --- a/cpp/test/IceGrid/deployer/AllTests.cpp +++ b/cpp/test/IceGrid/deployer/AllTests.cpp @@ -546,6 +546,14 @@ allTests(const Ice::CommunicatorPtr& comm) test(obj->getProperty("LogFilePath") == "test-Server1.log"); test(obj->getProperty("LogFilePath-Server1") == "test.log"); test(obj->getProperty("PropertyWithSpaces") == " test "); + // \ is escaped in C++ string literals + test(obj->getProperty("WindowsPath") == "C:\\Program Files (x86)\\ZeroC\\"); + test(obj->getProperty("UNCPath") == "\\\\server\\foo bar\\file"); + test(obj->getProperty("PropertyWith=") == "foo=bar"); + test(obj->getProperty("PropertyWithHash") == "foo#bar"); + test(obj->getProperty("PropertyWithTab") == "foo\tbar"); + test(obj->getProperty("PropertyWithEscapeSpace") == "foo\\ "); + test(obj->getProperty("PropertyWithProperty") == "Plugin.EntryPoint=foo:bar --Ice.Config=\\\\\\server\\foo bar\\file.cfg"); cout << "ok" << endl; cout << "testing service configuration... " << flush; @@ -556,6 +564,14 @@ allTests(const Ice::CommunicatorPtr& comm) test(obj->getProperty("LogFilePath") == "test-Service1.log"); test(obj->getProperty("LogFilePath-Service1") == "test.log"); test(obj->getProperty("PropertyWithSpaces") == " test "); + // \ is escaped in C++ string literals + test(obj->getProperty("WindowsPath") == "C:\\Program Files (x86)\\ZeroC\\"); + test(obj->getProperty("UNCPath") == "\\\\server\\foo bar\\file"); + test(obj->getProperty("PropertyWith=") == "foo=bar"); + test(obj->getProperty("PropertyWithHash") == "foo#bar"); + test(obj->getProperty("PropertyWithTab") == "foo\tbar"); + test(obj->getProperty("PropertyWithEscapeSpace") == "foo\\ "); + test(obj->getProperty("PropertyWithProperty") == "Plugin.EntryPoint=foo:bar --Ice.Config=\\\\\\server\\foo bar\\file.cfg"); obj = TestIntfPrx::checkedCast(comm->stringToProxy("IceBox2-Service2@IceBox2Service2Adapter")); test(obj->getProperty("Service2.Type") == "freeze"); diff --git a/cpp/test/IceGrid/deployer/server.xml b/cpp/test/IceGrid/deployer/server.xml index e4c4f3e2bd4..abf33b191cd 100644 --- a/cpp/test/IceGrid/deployer/server.xml +++ b/cpp/test/IceGrid/deployer/server.xml @@ -38,6 +38,14 @@ <property name="Ice.Warn.Connections" value="1"/> <property name="PropertyWithSpaces" value=" test "/> + <property name="WindowsPath" value="C:\Program Files (x86)\ZeroC\"/> + <property name="UNCPath" value="\\server\foo bar\file"/> + <property name="PropertyWith=" value="foo=bar"/> + <property name="PropertyWithHash" value="foo#bar"/> + <property name="PropertyWithTab" value="foo	bar"/> + <property name="PropertyWithEscapeSpace" value="foo\ "/> + <property name="PropertyWithProperty" + value="Plugin.EntryPoint=foo:bar --Ice.Config=\\\server\foo bar\file.cfg"/> <include file="varproperties.xml"/> diff --git a/cpp/test/IceGrid/deployer/service.xml b/cpp/test/IceGrid/deployer/service.xml index f564c51a0db..60dd215ebc7 100644 --- a/cpp/test/IceGrid/deployer/service.xml +++ b/cpp/test/IceGrid/deployer/service.xml @@ -19,7 +19,15 @@ <property name="${name}.ServiceName" value="${name}"/> <property name="PropertyWithSpaces" value=" test "/> - + <property name="WindowsPath" value="C:\Program Files (x86)\ZeroC\"/> + <property name="UNCPath" value="\\server\foo bar\file"/> + <property name="PropertyWith=" value="foo=bar"/> + <property name="PropertyWithHash" value="foo#bar"/> + <property name="PropertyWithTab" value="foo	bar"/> + <property name="PropertyWithEscapeSpace" value="foo\ "/> + <property name="PropertyWithProperty" + value="Plugin.EntryPoint=foo:bar --Ice.Config=\\\server\foo bar\file.cfg"/> + <include file="varproperties.xml"/> <property name="AppVarOverridedByParamProp" value="${AppVarOverridedByParam}"/> |