diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/Ice/InputStream.cpp | 21 | ||||
-rw-r--r-- | cpp/src/Ice/Instance.cpp | 3 | ||||
-rw-r--r-- | cpp/src/Ice/Instance.h | 2 | ||||
-rw-r--r-- | cpp/src/Ice/PropertyNames.cpp | 3 | ||||
-rw-r--r-- | cpp/src/Ice/PropertyNames.h | 2 | ||||
-rw-r--r-- | cpp/test/Ice/objects/AllTests.cpp | 20 | ||||
-rw-r--r-- | cpp/test/Ice/objects/Client.cpp | 2 | ||||
-rw-r--r-- | cpp/test/Ice/objects/Collocated.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/objects/Test.ice | 3 | ||||
-rw-r--r-- | cpp/test/Ice/objects/TestI.cpp | 14 | ||||
-rw-r--r-- | cpp/test/Ice/objects/TestI.h | 3 | ||||
-rw-r--r-- | cpp/test/Ice/optional/AllTests.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/optional/Client.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/optional/Server.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/optional/ServerAMD.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/slicing/objects/Client.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/slicing/objects/Server.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/slicing/objects/ServerAMD.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/stream/Client.cpp | 4 |
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); } |