summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/src/Ice/InputStream.cpp21
-rw-r--r--cpp/src/Ice/Instance.cpp3
-rw-r--r--cpp/src/Ice/Instance.h2
-rw-r--r--cpp/src/Ice/PropertyNames.cpp3
-rw-r--r--cpp/src/Ice/PropertyNames.h2
-rw-r--r--cpp/test/Ice/objects/AllTests.cpp20
-rw-r--r--cpp/test/Ice/objects/Client.cpp2
-rw-r--r--cpp/test/Ice/objects/Collocated.cpp1
-rw-r--r--cpp/test/Ice/objects/Test.ice3
-rw-r--r--cpp/test/Ice/objects/TestI.cpp14
-rw-r--r--cpp/test/Ice/objects/TestI.h3
-rw-r--r--cpp/test/Ice/optional/AllTests.cpp1
-rw-r--r--cpp/test/Ice/optional/Client.cpp1
-rw-r--r--cpp/test/Ice/optional/Server.cpp1
-rw-r--r--cpp/test/Ice/optional/ServerAMD.cpp1
-rw-r--r--cpp/test/Ice/slicing/objects/Client.cpp1
-rw-r--r--cpp/test/Ice/slicing/objects/Server.cpp1
-rw-r--r--cpp/test/Ice/slicing/objects/ServerAMD.cpp1
-rw-r--r--cpp/test/Ice/stream/Client.cpp4
19 files changed, 78 insertions, 7 deletions
diff --git a/cpp/src/Ice/InputStream.cpp b/cpp/src/Ice/InputStream.cpp
index d0c4c91d9fc..3c4686e979d 100644
--- a/cpp/src/Ice/InputStream.cpp
+++ b/cpp/src/Ice/InputStream.cpp
@@ -1819,12 +1819,17 @@ Ice::InputStream::EncapsDecoder::addPatchEntry(Int index, PatchFunc patchFunc, v
assert(index > 0);
//
- // Check if we already unmarshaled the object. If that's the case,
- // just patch the object smart pointer and we're done.
+ // Check if we already unmarshaled the object. If that's the case, just patch the object smart pointer
+ // and we're done. A null value indicates we've encountered a cycle and Ice.AllowClassCycles is false.
//
IndexToPtrMap::iterator p = _unmarshaledMap.find(index);
if(p != _unmarshaledMap.end())
{
+ if (p->second == ICE_NULLPTR)
+ {
+ assert(!_stream->_instance->acceptClassCycles());
+ throw MarshalException(__FILE__, __LINE__, "cycle detected during Value unmarshaling");
+ }
(*patchFunc)(patchAddr, p->second);
return;
}
@@ -1862,7 +1867,10 @@ Ice::InputStream::EncapsDecoder::unmarshal(Int index, const Ice::ValuePtr& v)
// Add the object to the map of unmarshaled instances, this must
// be done before reading the instances (for circular references).
//
- _unmarshaledMap.insert(make_pair(index, v));
+ // If circular references are not allowed we insert null (for cycle detection) and add
+ // the object to the map once it has been fully unmarshaled.
+ //
+ _unmarshaledMap.insert(make_pair(index, _stream->_instance->acceptClassCycles() ? v : Ice::ValuePtr()));
//
// Read the object.
@@ -1915,6 +1923,13 @@ Ice::InputStream::EncapsDecoder::unmarshal(Int index, const Ice::ValuePtr& v)
_valueList.clear();
}
}
+
+ if(!_stream->_instance->acceptClassCycles())
+ {
+ // This class has been fully unmarshaled without creating any cycles
+ // It can be added to the map now.
+ _unmarshaledMap[index] = v;
+ }
}
void
diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp
index e0c06b52a9b..7a1b5952157 100644
--- a/cpp/src/Ice/Instance.cpp
+++ b/cpp/src/Ice/Instance.cpp
@@ -950,6 +950,7 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi
_classGraphDepthMax(0),
_collectObjects(false),
_toStringMode(ICE_ENUM(ToStringMode, Unicode)),
+ _acceptClassCycles(false),
_implicitContext(0),
_stringConverter(Ice::getProcessStringConverter()),
_wstringConverter(Ice::getProcessWstringConverter()),
@@ -1227,6 +1228,8 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi
throw InitializationException(__FILE__, __LINE__, "The value for Ice.ToStringMode must be Unicode, ASCII or Compat");
}
+ const_cast<bool&>(_acceptClassCycles) = _initData.properties->getPropertyAsInt("Ice.AcceptClassCycles") > 0;
+
const_cast<ImplicitContextIPtr&>(_implicitContext) =
ImplicitContextI::create(_initData.properties->getProperty("Ice.ImplicitContext"));
diff --git a/cpp/src/Ice/Instance.h b/cpp/src/Ice/Instance.h
index 70e9c249e42..150167190d8 100644
--- a/cpp/src/Ice/Instance.h
+++ b/cpp/src/Ice/Instance.h
@@ -106,6 +106,7 @@ public:
size_t classGraphDepthMax() const { return _classGraphDepthMax; }
bool collectObjects() const { return _collectObjects; }
Ice::ToStringMode toStringMode() const { return _toStringMode; }
+ bool acceptClassCycles() const { return _acceptClassCycles; }
const ACMConfig& clientACM() const;
const ACMConfig& serverACM() const;
@@ -175,6 +176,7 @@ private:
const size_t _classGraphDepthMax; // Immutable, not reset by destroy().
const bool _collectObjects; // Immutable, not reset by destroy().
const Ice::ToStringMode _toStringMode; // Immutable, not reset by destroy()
+ const bool _acceptClassCycles; // Immutable, not reset by destroy()
ACMConfig _clientACM;
ACMConfig _serverACM;
RouterManagerPtr _routerManager;
diff --git a/cpp/src/Ice/PropertyNames.cpp b/cpp/src/Ice/PropertyNames.cpp
index 9d332d8618a..da4d0af3534 100644
--- a/cpp/src/Ice/PropertyNames.cpp
+++ b/cpp/src/Ice/PropertyNames.cpp
@@ -1,7 +1,7 @@
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
-// Generated by makeprops.py from file ./config/PropertyNames.xml, Fri Sep 6 18:11:04 2019
+// Generated by makeprops.py from file ./config/PropertyNames.xml, Thu Jul 2 14:55:02 2020
// IMPORTANT: Do not edit this file -- any edits made here will be lost!
@@ -9,6 +9,7 @@
const IceInternal::Property IcePropsData[] =
{
+ IceInternal::Property("Ice.AcceptClassCycles", false, 0),
IceInternal::Property("Ice.ACM.Client", true, 0),
IceInternal::Property("Ice.ACM.Server", true, 0),
IceInternal::Property("Ice.ACM.Timeout", false, 0),
diff --git a/cpp/src/Ice/PropertyNames.h b/cpp/src/Ice/PropertyNames.h
index 9c057af4afe..8f65258d805 100644
--- a/cpp/src/Ice/PropertyNames.h
+++ b/cpp/src/Ice/PropertyNames.h
@@ -1,7 +1,7 @@
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
-// Generated by makeprops.py from file ./config/PropertyNames.xml, Fri Sep 6 18:11:04 2019
+// Generated by makeprops.py from file ./config/PropertyNames.xml, Thu Jul 2 14:55:02 2020
// IMPORTANT: Do not edit this file -- any edits made here will be lost!
diff --git a/cpp/test/Ice/objects/AllTests.cpp b/cpp/test/Ice/objects/AllTests.cpp
index 65134a2c49e..c84b73d51a9 100644
--- a/cpp/test/Ice/objects/AllTests.cpp
+++ b/cpp/test/Ice/objects/AllTests.cpp
@@ -604,5 +604,25 @@ allTests(Test::TestHelper* helper)
}
cout << "ok" << endl;
+ cout << "testing sending class cycle... " << flush;
+ {
+ RecursivePtr rec = ICE_MAKE_SHARED(Recursive);
+ rec->v = rec;
+ bool acceptsCycles = initial->acceptsClassCycles();
+ try
+ {
+ initial->setCycle(rec);
+ test(acceptsCycles);
+ }
+ catch(const Ice::UnknownLocalException&)
+ {
+ // expected when the remote server does not accept cycles
+ // and throws a MarshalException
+ test(!acceptsCycles);
+ }
+ rec->v = ICE_NULLPTR;
+ }
+ cout << "ok" << endl;
+
return initial;
}
diff --git a/cpp/test/Ice/objects/Client.cpp b/cpp/test/Ice/objects/Client.cpp
index 4d5dc868b83..a27c51e17f6 100644
--- a/cpp/test/Ice/objects/Client.cpp
+++ b/cpp/test/Ice/objects/Client.cpp
@@ -118,7 +118,7 @@ void
Client::run(int argc, char** argv)
{
Ice::PropertiesPtr properties = createTestProperties(argc, argv);
-
+ properties->setProperty("Ice.AcceptClassCycles", "1");
#ifndef ICE_CPP11_MAPPING
properties->setProperty("Ice.CollectObjects", "1");
#endif
diff --git a/cpp/test/Ice/objects/Collocated.cpp b/cpp/test/Ice/objects/Collocated.cpp
index eb4434fbe39..0633cfa5d13 100644
--- a/cpp/test/Ice/objects/Collocated.cpp
+++ b/cpp/test/Ice/objects/Collocated.cpp
@@ -110,6 +110,7 @@ void
Collocated::run(int argc, char** argv)
{
Ice::PropertiesPtr properties = createTestProperties(argc, argv);
+ properties->setProperty("Ice.AcceptClassCycles", "1");
#ifndef ICE_CPP11_MAPPING
properties->setProperty("Ice.CollectObjects", "1");
#endif
diff --git a/cpp/test/Ice/objects/Test.ice b/cpp/test/Ice/objects/Test.ice
index 38214e39951..a89b9beb0e8 100644
--- a/cpp/test/Ice/objects/Test.ice
+++ b/cpp/test/Ice/objects/Test.ice
@@ -222,6 +222,9 @@ interface Initial
void setRecursive(Recursive p);
bool supportsClassGraphDepthMax();
+ void setCycle(Recursive r);
+ bool acceptsClassCycles();
+
["marshaled-result"] B getMB();
["amd", "marshaled-result"] B getAMDMB();
diff --git a/cpp/test/Ice/objects/TestI.cpp b/cpp/test/Ice/objects/TestI.cpp
index 9cfd4c395eb..abf4154e59e 100644
--- a/cpp/test/Ice/objects/TestI.cpp
+++ b/cpp/test/Ice/objects/TestI.cpp
@@ -187,6 +187,20 @@ InitialI::supportsClassGraphDepthMax(const Ice::Current&)
return true;
}
+void
+InitialI::setCycle(ICE_IN(RecursivePtr) r, const Ice::Current&)
+{
+ // break the cycle
+ assert(r);
+ r->v = ICE_NULLPTR;
+}
+
+bool
+InitialI::acceptsClassCycles(const Ice::Current& c)
+{
+ return c.adapter->getCommunicator()->getProperties()->getPropertyAsInt("Ice.AcceptClassCycles") > 0;
+}
+
#ifdef ICE_CPP11_MAPPING
InitialI::GetMBMarshaledResult
InitialI::getMB(const Ice::Current& current)
diff --git a/cpp/test/Ice/objects/TestI.h b/cpp/test/Ice/objects/TestI.h
index 3b265a19664..78874dbb91b 100644
--- a/cpp/test/Ice/objects/TestI.h
+++ b/cpp/test/Ice/objects/TestI.h
@@ -93,6 +93,9 @@ public:
virtual void setRecursive(ICE_IN(Test::RecursivePtr), const Ice::Current&);
virtual bool supportsClassGraphDepthMax(const Ice::Current&);
+ virtual void setCycle(ICE_IN(Test::RecursivePtr), const Ice::Current&);
+ virtual bool acceptsClassCycles(const Ice::Current&);
+
#ifdef ICE_CPP11_MAPPING
virtual GetMBMarshaledResult getMB(const Ice::Current&);
virtual void getAMDMBAsync(std::function<void(const GetAMDMBMarshaledResult&)>,
diff --git a/cpp/test/Ice/optional/AllTests.cpp b/cpp/test/Ice/optional/AllTests.cpp
index 7b00e0a421c..369d2228cc6 100644
--- a/cpp/test/Ice/optional/AllTests.cpp
+++ b/cpp/test/Ice/optional/AllTests.cpp
@@ -587,6 +587,7 @@ allTests(Test::TestHelper* helper, bool)
mo1->k = mo1;
MultiOptionalPtr mo5 = ICE_DYNAMIC_CAST(MultiOptional, initial->pingPong(mo1));
+
test(mo5->a == mo1->a);
test(mo5->b == mo1->b);
test(mo5->c == mo1->c);
diff --git a/cpp/test/Ice/optional/Client.cpp b/cpp/test/Ice/optional/Client.cpp
index 1f2bb2edb45..4806e2f02cf 100644
--- a/cpp/test/Ice/optional/Client.cpp
+++ b/cpp/test/Ice/optional/Client.cpp
@@ -20,6 +20,7 @@ void
Client::run(int argc, char** argv)
{
Ice::PropertiesPtr properties = createTestProperties(argc, argv);
+ properties->setProperty("Ice.AcceptClassCycles", "1");
#ifndef ICE_CPP11_MAPPING
properties->setProperty("Ice.CollectObjects", "1");
#endif
diff --git a/cpp/test/Ice/optional/Server.cpp b/cpp/test/Ice/optional/Server.cpp
index f526d0355d9..a84d6694b7e 100644
--- a/cpp/test/Ice/optional/Server.cpp
+++ b/cpp/test/Ice/optional/Server.cpp
@@ -20,6 +20,7 @@ void
Server::run(int argc, char** argv)
{
Ice::PropertiesPtr properties = createTestProperties(argc, argv);
+ properties->setProperty("Ice.AcceptClassCycles", "1");
#ifndef ICE_CPP11_MAPPING
properties->setProperty("Ice.CollectObjects", "1");
#endif
diff --git a/cpp/test/Ice/optional/ServerAMD.cpp b/cpp/test/Ice/optional/ServerAMD.cpp
index bdc012694ce..f9d16fed20f 100644
--- a/cpp/test/Ice/optional/ServerAMD.cpp
+++ b/cpp/test/Ice/optional/ServerAMD.cpp
@@ -19,6 +19,7 @@ void
ServerAMD::run(int argc, char** argv)
{
Ice::PropertiesPtr properties = createTestProperties(argc, argv);
+ properties->setProperty("Ice.AcceptClassCycles", "1");
#ifndef ICE_CPP11_MAPPING
properties->setProperty("Ice.CollectObjects", "1");
#endif
diff --git a/cpp/test/Ice/slicing/objects/Client.cpp b/cpp/test/Ice/slicing/objects/Client.cpp
index 537d7e9d216..b9f217e495d 100644
--- a/cpp/test/Ice/slicing/objects/Client.cpp
+++ b/cpp/test/Ice/slicing/objects/Client.cpp
@@ -23,6 +23,7 @@ Client::run(int argc, char** argv)
//
// For this test, we enable object collection.
//
+ properties->setProperty("Ice.AcceptClassCycles", "1");
properties->setProperty("Ice.CollectObjects", "1");
Ice::CommunicatorHolder communicator = initialize(argc, argv, properties);
diff --git a/cpp/test/Ice/slicing/objects/Server.cpp b/cpp/test/Ice/slicing/objects/Server.cpp
index f1cd93e6ae3..b7ca13be31b 100644
--- a/cpp/test/Ice/slicing/objects/Server.cpp
+++ b/cpp/test/Ice/slicing/objects/Server.cpp
@@ -19,6 +19,7 @@ void
Server::run(int argc, char** argv)
{
Ice::PropertiesPtr properties = createTestProperties(argc, argv);
+ properties->setProperty("Ice.AcceptClassCycles", "1");
#ifndef ICE_CPP11_MAPPING
properties->setProperty("Ice.CollectObjects", "1");
#endif
diff --git a/cpp/test/Ice/slicing/objects/ServerAMD.cpp b/cpp/test/Ice/slicing/objects/ServerAMD.cpp
index ab4df8a0f5e..e7e60f6998f 100644
--- a/cpp/test/Ice/slicing/objects/ServerAMD.cpp
+++ b/cpp/test/Ice/slicing/objects/ServerAMD.cpp
@@ -19,6 +19,7 @@ void
ServerAMD::run(int argc, char** argv)
{
Ice::PropertiesPtr properties = createTestProperties(argc, argv);
+ properties->setProperty("Ice.AcceptClassCycles", "1");
#ifndef ICE_CPP11_MAPPING
properties->setProperty("Ice.CollectObjects", "1");
#endif
diff --git a/cpp/test/Ice/stream/Client.cpp b/cpp/test/Ice/stream/Client.cpp
index 23a2be692df..879b93ffb61 100644
--- a/cpp/test/Ice/stream/Client.cpp
+++ b/cpp/test/Ice/stream/Client.cpp
@@ -1365,7 +1365,9 @@ public:
void
Client::run(int argc, char** argv)
{
- Ice::CommunicatorHolder communicator = initialize(argc, argv);
+ Ice::PropertiesPtr properties = createTestProperties(argc, argv);
+ properties->setProperty("Ice.AcceptClassCycles", "1");
+ Ice::CommunicatorHolder communicator = initialize(argc, argv, properties);
void allTests(Test::TestHelper*);
allTests(this);
}