summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/IceGrid/NodeCache.cpp22
-rw-r--r--cpp/src/IceGrid/Util.cpp71
-rwxr-xr-xcpp/src/IceGrid/Util.h2
-rw-r--r--cpp/test/IceGrid/deployer/AllTests.cpp16
-rw-r--r--cpp/test/IceGrid/deployer/server.xml8
-rw-r--r--cpp/test/IceGrid/deployer/service.xml10
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&#9;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&#9;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}"/>