diff options
Diffstat (limited to 'csharp/src')
-rw-r--r-- | csharp/src/Ice/InputStream.cs | 110 | ||||
-rw-r--r-- | csharp/src/Ice/Instance.cs | 20 | ||||
-rw-r--r-- | csharp/src/Ice/PropertyNames.cs | 3 |
3 files changed, 112 insertions, 21 deletions
diff --git a/csharp/src/Ice/InputStream.cs b/csharp/src/Ice/InputStream.cs index c942e132a82..0dd8c98b624 100644 --- a/csharp/src/Ice/InputStream.cs +++ b/csharp/src/Ice/InputStream.cs @@ -245,7 +245,7 @@ namespace Ice _instance = instance; _traceSlicing = _instance.traceLevels().slicing > 0; - + _classGraphDepthMax = _instance.classGraphDepthMax(); _valueFactoryManager = _instance.initializationData().valueFactoryManager; _logger = _instance.initializationData().logger; _classResolver = _instance.resolveClass; @@ -258,6 +258,7 @@ namespace Ice _encapsStack = null; _encapsCache = null; _traceSlicing = false; + _classGraphDepthMax = 0x7fffffff; _closure = null; _sliceValues = true; _startSeq = -1; @@ -360,6 +361,22 @@ namespace Ice } /// <summary> + /// Set the maximum depth allowed for graph of Slice class instances. + /// </summary> + /// <param name="classGraphDepthMax">The maximum depth.</param> + public void setClassGraphDepthMax(int classGraphDepthMax) + { + if(classGraphDepthMax < 1) + { + _classGraphDepthMax = 0x7fffffff; + } + else + { + _classGraphDepthMax = classGraphDepthMax; + } + } + + /// <summary> /// Retrieves the closure object associated with this stream. /// </summary> /// <returns>The closure object.</returns> @@ -413,6 +430,10 @@ namespace Ice other._sliceValues = _sliceValues; _sliceValues = tmpSliceValues; + int tmpClassGraphDepthMax = other._classGraphDepthMax; + other._classGraphDepthMax = _classGraphDepthMax; + _classGraphDepthMax = tmpClassGraphDepthMax; + // // Swap is never called for InputStreams that have encapsulations being read. However, // encapsulations might still be set in case un-marshalling failed. We just @@ -2733,12 +2754,27 @@ namespace Ice abstract private class EncapsDecoder { - internal EncapsDecoder(InputStream stream, Encaps encaps, bool sliceValues, ValueFactoryManager f, + protected struct PatchEntry + { + public PatchEntry(System.Action<Value> cb, int classGraphDepth) + { + this.cb = cb; + this.classGraphDepth = classGraphDepth; + } + + public System.Action<Value> cb; + public int classGraphDepth; + }; + + internal EncapsDecoder(InputStream stream, Encaps encaps, bool sliceValues, + int classGraphDepthMax, ValueFactoryManager f, System.Func<string, Type> cr) { _stream = stream; _encaps = encaps; _sliceValues = sliceValues; + _classGraphDepthMax = classGraphDepthMax; + _classGraphDepth = 0; _valueFactoryManager = f; _classResolver = cr; _typeIdIndex = 0; @@ -2889,7 +2925,7 @@ namespace Ice if(_patchMap == null) { - _patchMap = new Dictionary<int, LinkedList<System.Action<Value>>>(); + _patchMap = new Dictionary<int, LinkedList<PatchEntry>>(); } // @@ -2897,21 +2933,21 @@ namespace Ice // the callback will be called when the instance is // unmarshaled. // - LinkedList<System.Action<Value>> l; + LinkedList<PatchEntry> l; if(!_patchMap.TryGetValue(index, out l)) { // // We have no outstanding instances to be patched for this // index, so make a new entry in the patch map. // - l = new LinkedList<System.Action<Value>>(); + l = new LinkedList<PatchEntry>(); _patchMap.Add(index, l); } // // Append a patch entry for this instance. // - l.AddLast(cb); + l.AddLast(new PatchEntry(cb, _classGraphDepth)); } protected void unmarshal(int index, Value v) @@ -2932,7 +2968,7 @@ namespace Ice // // Patch all instances now that the instance is unmarshaled. // - LinkedList<System.Action<Value>> l; + LinkedList<PatchEntry> l; if(_patchMap.TryGetValue(index, out l)) { Debug.Assert(l.Count > 0); @@ -2940,9 +2976,9 @@ namespace Ice // // Patch all pointers that refer to the instance. // - foreach(System.Action<Value> cb in l) + foreach(PatchEntry entry in l) { - cb(v); + entry.cb(v); } // @@ -3001,13 +3037,15 @@ namespace Ice protected readonly InputStream _stream; protected readonly Encaps _encaps; protected readonly bool _sliceValues; + protected readonly int _classGraphDepthMax; + protected int _classGraphDepth; protected ValueFactoryManager _valueFactoryManager; protected System.Func<string, Type> _classResolver; // // Encapsulation attributes for object unmarshaling. // - protected Dictionary<int, LinkedList<System.Action<Value>> > _patchMap; + protected Dictionary<int, LinkedList<PatchEntry>> _patchMap; private Dictionary<int, Value> _unmarshaledMap; private Dictionary<int, string> _typeIdMap; private int _typeIdIndex; @@ -3017,9 +3055,9 @@ namespace Ice private sealed class EncapsDecoder10 : EncapsDecoder { - internal EncapsDecoder10(InputStream stream, Encaps encaps, bool sliceValues, ValueFactoryManager f, - System.Func<string, Type> cr) - : base(stream, encaps, sliceValues, f, cr) + internal EncapsDecoder10(InputStream stream, Encaps encaps, bool sliceValues, int classGraphDepthMax, + ValueFactoryManager f, System.Func<string, Type> cr) + : base(stream, encaps, sliceValues, classGraphDepthMax, f, cr) { _sliceType = SliceType.NoSlice; } @@ -3297,6 +3335,30 @@ namespace Ice } // + // Compute the biggest class graph depth of this object. To compute this, + // we get the class graph depth of each ancestor from the patch map and + // keep the biggest one. + // + _classGraphDepth = 0; + LinkedList<PatchEntry> l; + if(_patchMap != null && _patchMap.TryGetValue(index, out l)) + { + Debug.Assert(l.Count > 0); + foreach(PatchEntry entry in l) + { + if(entry.classGraphDepth > _classGraphDepth) + { + _classGraphDepth = entry.classGraphDepth; + } + } + } + + if(++_classGraphDepth > _classGraphDepthMax) + { + throw new MarshalException("maximum class graph depth reached"); + } + + // // Unmarshal the instance and add it to the map of unmarshaled instances. // unmarshal(index, v); @@ -3313,9 +3375,9 @@ namespace Ice private sealed class EncapsDecoder11 : EncapsDecoder { - internal EncapsDecoder11(InputStream stream, Encaps encaps, bool sliceValues, ValueFactoryManager f, - System.Func<string, Type> cr, System.Func<int, string> r) - : base(stream, encaps, sliceValues, f, cr) + internal EncapsDecoder11(InputStream stream, Encaps encaps, bool sliceValues, int classGraphDepthMax, + ValueFactoryManager f, System.Func<string, Type> cr, System.Func<int, string> r) + : base(stream, encaps, sliceValues, classGraphDepthMax, f, cr) { _compactIdResolver = r; _current = null; @@ -3841,11 +3903,18 @@ namespace Ice startSlice(); // Read next Slice header for next iteration. } + if(++_classGraphDepth > _classGraphDepthMax) + { + throw new MarshalException("maximum class graph depth reached"); + } + // // Unmarshal the instance. // unmarshal(index, v); + --_classGraphDepth; + if(_current == null && _patchMap != null && _patchMap.Count > 0) { // @@ -4008,19 +4077,20 @@ namespace Ice { if(_encapsStack.encoding_1_0) { - _encapsStack.decoder = new EncapsDecoder10(this, _encapsStack, _sliceValues, _valueFactoryManager, - _classResolver); + _encapsStack.decoder = new EncapsDecoder10(this, _encapsStack, _sliceValues, _classGraphDepthMax, + _valueFactoryManager, _classResolver); } else { - _encapsStack.decoder = new EncapsDecoder11(this, _encapsStack, _sliceValues, _valueFactoryManager, - _classResolver, _compactIdResolver); + _encapsStack.decoder = new EncapsDecoder11(this, _encapsStack, _sliceValues, _classGraphDepthMax, + _valueFactoryManager, _classResolver, _compactIdResolver); } } } private bool _sliceValues; private bool _traceSlicing; + private int _classGraphDepthMax; private int _startSeq; private int _minSeqSize; diff --git a/csharp/src/Ice/Instance.cs b/csharp/src/Ice/Instance.cs index a4a1c3e7c1d..423b24b96d2 100644 --- a/csharp/src/Ice/Instance.cs +++ b/csharp/src/Ice/Instance.cs @@ -336,6 +336,12 @@ namespace IceInternal return _batchAutoFlushSize; } + public int classGraphDepthMax() + { + // No mutex lock, immutable. + return _classGraphDepthMax; + } + public Ice.ToStringMode toStringMode() { @@ -857,6 +863,19 @@ namespace IceInternal } } + { + const int defaultValue = 100; + var num = _initData.properties.getPropertyAsIntWithDefault("Ice.ClassGraphDepthMax", defaultValue); + if(num < 1 || num > 0x7fffffff) + { + _classGraphDepthMax = 0x7fffffff; + } + else + { + _classGraphDepthMax = num; + } + } + string toStringModeStr = _initData.properties.getPropertyWithDefault("Ice.ToStringMode", "Unicode"); if(toStringModeStr == "Unicode") { @@ -1560,6 +1579,7 @@ namespace IceInternal private DefaultsAndOverrides _defaultsAndOverrides; // Immutable, not reset by destroy(). private int _messageSizeMax; // Immutable, not reset by destroy(). private int _batchAutoFlushSize; // Immutable, not reset by destroy(). + private int _classGraphDepthMax; // Immutable, not reset by destroy(). private Ice.ToStringMode _toStringMode; // Immutable, not reset by destroy(). private int _cacheMessageBuffers; // Immutable, not reset by destroy(). private ACMConfig _clientACM; // Immutable, not reset by destroy(). diff --git a/csharp/src/Ice/PropertyNames.cs b/csharp/src/Ice/PropertyNames.cs index b5fa1fec421..3d1359ac6de 100644 --- a/csharp/src/Ice/PropertyNames.cs +++ b/csharp/src/Ice/PropertyNames.cs @@ -6,7 +6,7 @@ // ICE_LICENSE file included in this distribution. // // ********************************************************************** -// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017 +// Generated by makeprops.py from file ./config/PropertyNames.xml, Thu Mar 23 15:24:16 2017 // IMPORTANT: Do not edit this file -- any edits made here will be lost! @@ -79,6 +79,7 @@ namespace IceInternal new Property(@"^Ice\.BatchAutoFlush$", true, null), new Property(@"^Ice\.BatchAutoFlushSize$", false, null), new Property(@"^Ice\.ChangeUser$", false, null), + new Property(@"^Ice\.ClassGraphDepthMax$", false, null), new Property(@"^Ice\.ClientAccessPolicyProtocol$", false, null), new Property(@"^Ice\.Compression\.Level$", false, null), new Property(@"^Ice\.CollectObjects$", false, null), |