3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
11 ** Purpose: DeSerializes Binary Wire format
14 ===========================================================*/
16 namespace System.Runtime.Serialization.Formatters.Binary {
19 using System.Globalization;
21 using System.Reflection;
22 using System.Collections;
24 using System.Runtime.Remoting;
25 using System.Runtime.Remoting.Messaging;
26 using System.Runtime.Serialization;
27 using System.Security.Permissions;
28 using System.Security;
29 using System.Diagnostics;
30 using System.Resources;
31 using System.Runtime.CompilerServices;
32 using System.Diagnostics.Contracts;
33 using StackCrawlMark = System.Threading.StackCrawlMark;
35 internal sealed class ObjectReader
38 // System.Serializer information
39 internal Stream m_stream;
40 internal ISurrogateSelector m_surrogates;
41 internal StreamingContext m_context;
42 internal ObjectManager m_objectManager;
43 internal InternalFE formatterEnums;
44 internal SerializationBinder m_binder;
46 // Top object and headers
48 internal bool bSimpleAssembly = false;
49 internal Object handlerObject;
50 internal Object m_topObject;
51 internal Header[] headers;
52 internal HeaderHandler handler;
53 internal SerObjectInfoInit serObjectInfoInit;
54 internal IFormatterConverter m_formatterConverter;
56 // Stack of Object ParseRecords
57 internal SerStack stack;
59 // ValueType Fixup Stack
60 private SerStack valueFixupStack;
63 internal Object[] crossAppDomainArray; //Set by the BinaryFormatter
65 //MethodCall and MethodReturn are handled special for perf reasons
66 private bool bFullDeserialization;
68 private bool bMethodCall;
69 private bool bMethodReturn;
70 private BinaryMethodCall binaryMethodCall;
71 private BinaryMethodReturn binaryMethodReturn;
72 private bool bIsCrossAppDomain;
75 private static FileIOPermission sfileIOPermission = new FileIOPermission(PermissionState.Unrestricted);
77 private SerStack ValueFixupStack
80 if (valueFixupStack == null)
81 valueFixupStack = new SerStack("ValueType Fixup Stack");
82 return valueFixupStack;
86 internal Object TopObject{
92 if (m_objectManager != null)
93 m_objectManager.TopObject = value;
97 internal void SetMethodCall(BinaryMethodCall binaryMethodCall)
100 this.binaryMethodCall = binaryMethodCall;
103 internal void SetMethodReturn(BinaryMethodReturn binaryMethodReturn)
105 bMethodReturn = true;
106 this.binaryMethodReturn = binaryMethodReturn;
110 internal ObjectReader(Stream stream, ISurrogateSelector selector, StreamingContext context, InternalFE formatterEnums, SerializationBinder binder)
114 throw new ArgumentNullException("stream", Environment.GetResourceString("ArgumentNull_Stream"));
116 Contract.EndContractBlock();
118 SerTrace.Log(this, "Constructor ISurrogateSelector ", ((selector == null) ? "null selector " : "selector present"));
121 m_surrogates = selector;
125 #if !FEATURE_PAL && FEATURE_SERIALIZATION
126 // This is a hack to allow us to write a type-limiting deserializer
127 // when we know exactly what type to expect at the head of the
129 if (m_binder != null) {
130 ResourceReader.TypeLimitingDeserializationBinder tldBinder = m_binder as ResourceReader.TypeLimitingDeserializationBinder;
131 if (tldBinder != null)
132 tldBinder.ObjectReader = this;
134 #endif // !FEATURE_PAL && FEATURE_SERIALIZATION
136 this.formatterEnums = formatterEnums;
138 //SerTrace.Log( this, "Constructor formatterEnums.FEtopObject ",formatterEnums.FEtopObject);
142 #if FEATURE_REMOTING || MOBILE_LEGACY
143 [System.Security.SecurityCritical] // auto-generated
144 internal Object Deserialize(HeaderHandler handler, __BinaryParser serParser, bool fCheck, bool isCrossAppDomain, IMethodCallMessage methodCallMessage) {
145 if (serParser == null)
146 throw new ArgumentNullException("serParser", Environment.GetResourceString("ArgumentNull_WithParamName", serParser));
147 Contract.EndContractBlock();
150 SerTrace.Log( this, "Deserialize Entry handler", handler);
152 bFullDeserialization = false;
157 bMethodReturn = false;
158 bIsCrossAppDomain = isCrossAppDomain;
160 bSimpleAssembly = (formatterEnums.FEassemblyFormat == FormatterAssemblyStyle.Simple);
164 CodeAccessPermission.Demand(PermissionType.SecuritySerialization);
167 this.handler = handler;
169 Contract.Assert(!bFullDeserialization, "we just set bFullDeserialization to false");
171 // Will call back to ParseObject, ParseHeader for each object found
175 SerTrace.Log( this, "Deserialize Finished Parsing DoFixups");
178 if (bFullDeserialization)
179 m_objectManager.DoFixups();
183 if (!bMethodCall && !bMethodReturn)
186 if (TopObject == null)
187 throw new SerializationException(Environment.GetResourceString("Serialization_TopObject"));
189 //if TopObject has a surrogate then the actual object may be changed during special fixup
190 //So refresh it using topID.
191 if (HasSurrogate(TopObject.GetType()) && topId != 0)//Not yet resolved
192 TopObject = m_objectManager.GetObject(topId);
194 if (TopObject is IObjectReference)
196 TopObject = ((IObjectReference)TopObject).GetRealObject(m_context);
200 SerTrace.Log( this, "Deserialize Exit ",TopObject);
202 if (bFullDeserialization)
204 m_objectManager.RaiseDeserializationEvent(); // This will raise both IDeserialization and [OnDeserialized] events
207 // Return the headers if there is a handler
210 handlerObject = handler(headers);
215 Object[] methodCallArray = TopObject as Object[];
216 TopObject = binaryMethodCall.ReadArray(methodCallArray, handlerObject);
218 else if (bMethodReturn)
220 Object[] methodReturnArray = TopObject as Object[];
221 TopObject = binaryMethodReturn.ReadArray(methodReturnArray, methodCallMessage, handlerObject);
228 #if !FEATURE_REMOTING
229 internal Object Deserialize(HeaderHandler handler, __BinaryParser serParser, bool fCheck)
231 if (serParser == null)
232 throw new ArgumentNullException("serParser", Environment.GetResourceString("ArgumentNull_WithParamName", serParser));
233 Contract.EndContractBlock();
236 SerTrace.Log( this, "Deserialize Entry handler", handler);
238 bFullDeserialization = false;
243 bMethodReturn = false;
244 bIsCrossAppDomain = isCrossAppDomain;
246 bSimpleAssembly = (formatterEnums.FEassemblyFormat == FormatterAssemblyStyle.Simple);
250 CodeAccessPermission.Demand(PermissionType.SecuritySerialization);
253 this.handler = handler;
256 if (bFullDeserialization)
260 m_objectManager = new ObjectManager(m_surrogates, m_context, false, bIsCrossAppDomain);
262 m_objectManager = new ObjectManager(m_surrogates, m_context, false, false);
264 serObjectInfoInit = new SerObjectInfoInit();
267 // Will call back to ParseObject, ParseHeader for each object found
271 SerTrace.Log( this, "Deserialize Finished Parsing DoFixups");
274 if (bFullDeserialization)
275 m_objectManager.DoFixups();
279 if (!bMethodCall && !bMethodReturn)
282 if (TopObject == null)
283 throw new SerializationException(Environment.GetResourceString("Serialization_TopObject"));
285 //if TopObject has a surrogate then the actual object may be changed during special fixup
286 //So refresh it using topID.
287 if (HasSurrogate(TopObject.GetType()) && topId != 0)//Not yet resolved
288 TopObject = m_objectManager.GetObject(topId);
290 if (TopObject is IObjectReference)
292 TopObject = ((IObjectReference)TopObject).GetRealObject(m_context);
296 SerTrace.Log( this, "Deserialize Exit ",TopObject);
298 if (bFullDeserialization)
300 m_objectManager.RaiseDeserializationEvent(); // This will raise both IDeserialization and [OnDeserialized] events
303 // Return the headers if there is a handler
306 handlerObject = handler(headers);
311 Object[] methodCallArray = TopObject as Object[];
312 TopObject = binaryMethodCall.ReadArray(methodCallArray, handlerObject);
314 else if (bMethodReturn)
316 Object[] methodReturnArray = TopObject as Object[];
317 TopObject = binaryMethodReturn.ReadArray(methodReturnArray, methodCallMessage, handlerObject);
324 [System.Security.SecurityCritical] // auto-generated
325 private bool HasSurrogate(Type t){
326 if (m_surrogates == null)
328 ISurrogateSelector notUsed;
329 return m_surrogates.GetSurrogate(t, m_context, out notUsed) != null;
332 [System.Security.SecurityCritical] // auto-generated
333 private void CheckSerializable(Type t)
335 if (!t.IsSerializable && !HasSurrogate(t))
336 throw new SerializationException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Serialization_NonSerType"),
337 t.FullName, t.Assembly.FullName));
340 [System.Security.SecurityCritical] // auto-generated
341 private void InitFullDeserialization()
343 bFullDeserialization = true;
344 stack = new SerStack("ObjectReader Object Stack");
346 m_objectManager = new ObjectManager(m_surrogates, m_context, false, bIsCrossAppDomain);
348 m_objectManager = new ObjectManager(m_surrogates, m_context, false, false);
350 if (m_formatterConverter == null)
351 m_formatterConverter = new FormatterConverter();
355 internal Object CrossAppDomainArray(int index)
357 Contract.Assert((index < crossAppDomainArray.Length),
358 "[System.Runtime.Serialization.Formatters.BinaryObjectReader index out of range for CrossAppDomainArray]");
359 return crossAppDomainArray[index];
362 [System.Security.SecurityCritical] // auto-generated
363 internal ReadObjectInfo CreateReadObjectInfo(Type objectType)
365 return ReadObjectInfo.Create(objectType, m_surrogates, m_context, m_objectManager, serObjectInfoInit, m_formatterConverter, bSimpleAssembly);
368 [System.Security.SecurityCritical] // auto-generated
369 internal ReadObjectInfo CreateReadObjectInfo(Type objectType, String[] memberNames, Type[] memberTypes)
371 return ReadObjectInfo.Create(objectType, memberNames, memberTypes, m_surrogates, m_context, m_objectManager, serObjectInfoInit, m_formatterConverter, bSimpleAssembly);
375 // Main Parse routine, called by the XML Parse Handlers in XMLParser and also called internally to
376 [System.Security.SecurityCritical] // auto-generated
377 internal void Parse(ParseRecord pr)
380 SerTrace.Log( this, "Parse");
385 switch (pr.PRparseTypeEnum)
387 case InternalParseTypeE.SerializedStreamHeader:
388 ParseSerializedStreamHeader(pr);
390 case InternalParseTypeE.SerializedStreamHeaderEnd:
391 ParseSerializedStreamHeaderEnd(pr);
393 case InternalParseTypeE.Object:
396 case InternalParseTypeE.ObjectEnd:
399 case InternalParseTypeE.Member:
402 case InternalParseTypeE.MemberEnd:
405 case InternalParseTypeE.Body:
406 case InternalParseTypeE.BodyEnd:
407 case InternalParseTypeE.Envelope:
408 case InternalParseTypeE.EnvelopeEnd:
410 case InternalParseTypeE.Empty:
412 throw new SerializationException(Environment.GetResourceString("Serialization_XMLElement", pr.PRname));
418 // Styled ParseError output
419 private void ParseError(ParseRecord processing, ParseRecord onStack)
422 SerTrace.Log( this, " ParseError ",processing," ",onStack);
424 throw new SerializationException(Environment.GetResourceString("Serialization_ParseError",onStack.PRname+" "+((Enum)onStack.PRparseTypeEnum) + " "+processing.PRname+" "+((Enum)processing.PRparseTypeEnum)));
427 // Parse the SerializedStreamHeader element. This is the first element in the stream if present
428 private void ParseSerializedStreamHeader(ParseRecord pr)
431 SerTrace.Log( this, "SerializedHeader ",pr);
436 // Parse the SerializedStreamHeader end element. This is the last element in the stream if present
437 private void ParseSerializedStreamHeaderEnd(ParseRecord pr)
440 SerTrace.Log( this, "SerializedHeaderEnd ",pr);
446 private bool IsRemoting {
448 //return (m_context.State & (StreamingContextStates.Persistence|StreamingContextStates.File|StreamingContextStates.Clone)) == 0;
449 return (bMethodCall || bMethodReturn);
453 [System.Security.SecurityCritical] // auto-generated
454 internal void CheckSecurity(ParseRecord pr)
456 InternalST.SoapAssert(pr!=null, "[BinaryObjectReader.CheckSecurity]pr!=null");
457 Type t = pr.PRdtType;
458 if ((object)t != null){
460 if (typeof(MarshalByRefObject).IsAssignableFrom(t))
461 throw new ArgumentException(Environment.GetResourceString("Serialization_MBRAsMBV", t.FullName));
462 FormatterServices.CheckTypeSecurity(t, formatterEnums.FEsecurityLevel);
468 // New object encountered in stream
469 [System.Security.SecurityCritical] // auto-generated
470 private void ParseObject(ParseRecord pr)
473 SerTrace.Log( this, "ParseObject Entry ");
476 if (!bFullDeserialization)
477 InitFullDeserialization();
479 if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
480 topId = pr.PRobjectId;
482 if (pr.PRparseTypeEnum == InternalParseTypeE.Object)
484 stack.Push(pr); // Nested objects member names are already on stack
487 if (pr.PRobjectTypeEnum == InternalObjectTypeE.Array)
491 SerTrace.Log( this, "ParseObject Exit, ParseArray ");
496 // If the Type is null, this means we have a typeload issue
497 // mark the object with TypeLoadExceptionHolder
498 if ((object)pr.PRdtType == null)
500 pr.PRnewObj = new TypeLoadExceptionHolder(pr.PRkeyDt);
504 if (Object.ReferenceEquals(pr.PRdtType, Converter.typeofString))
506 // String as a top level object
507 if (pr.PRvalue != null)
509 pr.PRnewObj = pr.PRvalue;
510 if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
513 SerTrace.Log( this, "ParseObject String as top level, Top Object Resolved");
515 TopObject = pr.PRnewObj;
522 SerTrace.Log( this, "ParseObject String as an object");
525 RegisterObject(pr.PRnewObj, pr, (ParseRecord)stack.Peek());
531 // xml Doesn't have the value until later
536 CheckSerializable(pr.PRdtType);
538 if (IsRemoting && formatterEnums.FEsecurityLevel != TypeFilterLevel.Full)
539 pr.PRnewObj = FormatterServices.GetSafeUninitializedObject(pr.PRdtType);
542 pr.PRnewObj = FormatterServices.GetUninitializedObject(pr.PRdtType);
544 // Run the OnDeserializing methods
545 m_objectManager.RaiseOnDeserializingEvent(pr.PRnewObj);
548 if (pr.PRnewObj == null)
549 throw new SerializationException(Environment.GetResourceString("Serialization_TopObjectInstantiate",pr.PRdtType));
551 if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
554 SerTrace.Log( this, "ParseObject Top Object Resolved ",pr.PRnewObj.GetType());
556 TopObject = pr.PRnewObj;
559 if (pr.PRobjectInfo == null)
560 pr.PRobjectInfo = ReadObjectInfo.Create(pr.PRdtType, m_surrogates, m_context, m_objectManager, serObjectInfoInit, m_formatterConverter, bSimpleAssembly);
567 SerTrace.Log( this, "ParseObject Exit ");
571 // End of object encountered in stream
572 [System.Security.SecurityCritical] // auto-generated
573 private void ParseObjectEnd(ParseRecord pr)
576 SerTrace.Log( this, "ParseObjectEnd Entry ",pr.Trace());
578 ParseRecord objectPr = (ParseRecord)stack.Peek();
579 if (objectPr == null)
582 //Contract.Assert(objectPr != null, "[System.Runtime.Serialization.Formatters.ParseObjectEnd]objectPr != null");
585 SerTrace.Log( this, "ParseObjectEnd objectPr ",objectPr.Trace());
588 if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top)
591 SerTrace.Log( this, "ParseObjectEnd Top Object dtType ",objectPr.PRdtType);
593 if (Object.ReferenceEquals(objectPr.PRdtType, Converter.typeofString))
596 SerTrace.Log( this, "ParseObjectEnd Top String");
598 objectPr.PRnewObj = objectPr.PRvalue;
599 TopObject = objectPr.PRnewObj;
605 ParseRecord parentPr = (ParseRecord)stack.Peek();
607 if (objectPr.PRnewObj == null)
610 if (objectPr.PRobjectTypeEnum == InternalObjectTypeE.Array)
612 if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top)
615 SerTrace.Log( this, "ParseObjectEnd Top Object (Array) Resolved");
617 TopObject = objectPr.PRnewObj;
621 SerTrace.Log( this, "ParseArray RegisterObject ",objectPr.PRobjectId," ",objectPr.PRnewObj.GetType());
623 RegisterObject(objectPr.PRnewObj, objectPr, parentPr);
628 objectPr.PRobjectInfo.PopulateObjectMembers(objectPr.PRnewObj, objectPr.PRmemberData);
630 // Registration is after object is populated
631 if ((!objectPr.PRisRegistered) && (objectPr.PRobjectId > 0))
634 SerTrace.Log( this, "ParseObject Register Object ",objectPr.PRobjectId," ",objectPr.PRnewObj.GetType());
636 RegisterObject(objectPr.PRnewObj, objectPr, parentPr);
639 if (objectPr.PRisValueTypeFixup)
642 SerTrace.Log( this, "ParseObjectEnd ValueTypeFixup ",objectPr.PRnewObj.GetType());
644 ValueFixup fixup = (ValueFixup)ValueFixupStack.Pop(); //Value fixup
645 fixup.Fixup(objectPr, parentPr); // Value fixup
649 if (objectPr.PRobjectPositionEnum == InternalObjectPositionE.Top)
652 SerTrace.Log( this, "ParseObjectEnd Top Object Resolved ",objectPr.PRnewObj.GetType());
654 TopObject = objectPr.PRnewObj;
657 objectPr.PRobjectInfo.ObjectEnd();
660 SerTrace.Log( this, "ParseObjectEnd Exit ",objectPr.PRnewObj.GetType()," id: ",objectPr.PRobjectId);
666 // Array object encountered in stream
667 [System.Security.SecurityCritical] // auto-generated
668 private void ParseArray(ParseRecord pr)
670 SerTrace.Log( this, "ParseArray Entry");
672 long genId = pr.PRobjectId;
674 if (pr.PRarrayTypeEnum == InternalArrayTypeE.Base64)
676 SerTrace.Log( this, "ParseArray bin.base64 ",pr.PRvalue.Length," ",pr.PRvalue);
678 if (pr.PRvalue.Length > 0)
679 pr.PRnewObj = Convert.FromBase64String(pr.PRvalue);
681 pr.PRnewObj = new Byte[0];
683 if (stack.Peek() == pr)
685 SerTrace.Log( this, "ParseArray, bin.base64 has been stacked");
688 if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
690 TopObject = pr.PRnewObj;
693 ParseRecord parentPr = (ParseRecord)stack.Peek();
695 // Base64 can be registered at this point because it is populated
696 SerTrace.Log( this, "ParseArray RegisterObject ",pr.PRobjectId," ",pr.PRnewObj.GetType());
697 RegisterObject(pr.PRnewObj, pr, parentPr);
700 else if ((pr.PRnewObj != null) && Converter.IsWriteAsByteArray(pr.PRarrayElementTypeCode))
702 // Primtive typed Array has already been read
703 if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)
705 TopObject = pr.PRnewObj;
708 ParseRecord parentPr = (ParseRecord)stack.Peek();
710 // Primitive typed array can be registered at this point because it is populated
711 SerTrace.Log( this, "ParseArray RegisterObject ",pr.PRobjectId," ",pr.PRnewObj.GetType());
712 RegisterObject(pr.PRnewObj, pr, parentPr);
714 else if ((pr.PRarrayTypeEnum == InternalArrayTypeE.Jagged) || (pr.PRarrayTypeEnum == InternalArrayTypeE.Single))
716 // Multidimensional jagged array or single array
717 SerTrace.Log( this, "ParseArray Before Jagged,Simple create ",pr.PRarrayElementType," ",pr.PRlengthA[0]);
718 bool bCouldBeValueType = true;
719 if ((pr.PRlowerBoundA == null) || (pr.PRlowerBoundA[0] == 0))
721 if (Object.ReferenceEquals(pr.PRarrayElementType, Converter.typeofString))
723 pr.PRobjectA = new String[pr.PRlengthA[0]];
724 pr.PRnewObj = pr.PRobjectA;
725 bCouldBeValueType = false;
727 else if (Object.ReferenceEquals(pr.PRarrayElementType, Converter.typeofObject))
729 pr.PRobjectA = new Object[pr.PRlengthA[0]];
730 pr.PRnewObj = pr.PRobjectA;
731 bCouldBeValueType = false;
733 else if ((object)pr.PRarrayElementType != null) {
734 pr.PRnewObj = Array.UnsafeCreateInstance(pr.PRarrayElementType, pr.PRlengthA[0]);
736 pr.PRisLowerBound = false;
740 if ((object)pr.PRarrayElementType != null) {
741 pr.PRnewObj = Array.UnsafeCreateInstance(pr.PRarrayElementType, pr.PRlengthA, pr.PRlowerBoundA);
743 pr.PRisLowerBound = true;
746 if (pr.PRarrayTypeEnum == InternalArrayTypeE.Single)
748 if (!pr.PRisLowerBound && (Converter.IsWriteAsByteArray(pr.PRarrayElementTypeCode)))
750 pr.PRprimitiveArray = new PrimitiveArray(pr.PRarrayElementTypeCode, (Array)pr.PRnewObj);
752 else if (bCouldBeValueType && (object)pr.PRarrayElementType != null)
754 if (!pr.PRarrayElementType.IsValueType && !pr.PRisLowerBound)
755 pr.PRobjectA = (Object[])pr.PRnewObj;
759 SerTrace.Log( this, "ParseArray Jagged,Simple Array ",pr.PRnewObj.GetType());
761 // For binary, headers comes in as an array of header objects
762 if (pr.PRobjectPositionEnum == InternalObjectPositionE.Headers)
764 SerTrace.Log( this, "ParseArray header array");
765 headers = (Header[])pr.PRnewObj;
768 pr.PRindexMap = new int[1];
771 else if (pr.PRarrayTypeEnum == InternalArrayTypeE.Rectangular)
775 pr.PRisLowerBound = false;
776 if (pr.PRlowerBoundA != null)
778 for (int i=0; i<pr.PRrank; i++)
780 if (pr.PRlowerBoundA[i] != 0)
781 pr.PRisLowerBound = true;
785 if ((object)pr.PRarrayElementType != null){
786 if (!pr.PRisLowerBound)
787 pr.PRnewObj = Array.UnsafeCreateInstance(pr.PRarrayElementType, pr.PRlengthA);
789 pr.PRnewObj = Array.UnsafeCreateInstance(pr.PRarrayElementType, pr.PRlengthA, pr.PRlowerBoundA);
792 SerTrace.Log( this, "ParseArray Rectangle Array ",pr.PRnewObj.GetType()," lower Bound ",pr.PRisLowerBound);
794 // Calculate number of items
796 for (int i=0; i<pr.PRrank; i++)
798 sum = sum*pr.PRlengthA[i];
800 pr.PRindexMap = new int[pr.PRrank];
801 pr.PRrectangularMap = new int[pr.PRrank];
802 pr.PRlinearlength = sum;
805 throw new SerializationException(Environment.GetResourceString("Serialization_ArrayType",((Enum)pr.PRarrayTypeEnum)));
810 SerTrace.Log( this, "ParseArray Exit");
814 // Builds a map for each item in an incoming rectangle array. The map specifies where the item is placed in the output Array Object
816 private void NextRectangleMap(ParseRecord pr)
818 // For each invocation, calculate the next rectangular array position
820 // indexMap 0 [0,0,0]
821 // indexMap 1 [0,0,1]
822 // indexMap 2 [0,0,2]
823 // indexMap 3 [0,0,3]
824 // indexMap 4 [0,1,0]
825 for (int irank = pr.PRrank-1; irank>-1; irank--)
827 // Find the current or lower dimension which can be incremented.
828 if (pr.PRrectangularMap[irank] < pr.PRlengthA[irank]-1)
830 // The current dimension is at maximum. Increase the next lower dimension by 1
831 pr.PRrectangularMap[irank]++;
832 if (irank < pr.PRrank-1)
834 // The current dimension and higher dimensions are zeroed.
835 for (int i = irank+1; i<pr.PRrank; i++)
836 pr.PRrectangularMap[i] = 0;
838 Array.Copy(pr.PRrectangularMap, pr.PRindexMap, pr.PRrank);
846 // Array object item encountered in stream
847 [System.Security.SecurityCritical] // auto-generated
848 private void ParseArrayMember(ParseRecord pr)
850 SerTrace.Log( this, "ParseArrayMember Entry");
851 ParseRecord objectPr = (ParseRecord)stack.Peek();
854 // Set up for inserting value into correct array position
855 if (objectPr.PRarrayTypeEnum == InternalArrayTypeE.Rectangular)
858 if (objectPr.PRmemberIndex > 0)
859 NextRectangleMap(objectPr); // Rectangle array, calculate position in array
860 if (objectPr.PRisLowerBound)
862 for (int i=0; i<objectPr.PRrank; i++)
864 objectPr.PRindexMap[i] = objectPr.PRrectangularMap[i] + objectPr.PRlowerBoundA[i];
870 if (!objectPr.PRisLowerBound)
872 objectPr.PRindexMap[0] = objectPr.PRmemberIndex; // Zero based array
875 objectPr.PRindexMap[0] = objectPr.PRlowerBoundA[0]+objectPr.PRmemberIndex; // Lower Bound based array
877 IndexTraceMessage("ParseArrayMember isLowerBound "+objectPr.PRisLowerBound+" indexMap ", objectPr.PRindexMap);
879 // Set Array element according to type of element
881 if (pr.PRmemberValueEnum == InternalMemberValueE.Reference)
885 // See if object has already been instantiated
886 Object refObj = m_objectManager.GetObject(pr.PRidRef);
889 // Object not instantiated
890 // Array fixup manager
891 IndexTraceMessage("ParseArrayMember Record Fixup "+objectPr.PRnewObj.GetType(), objectPr.PRindexMap);
892 int[] fixupIndex = new int[objectPr.PRrank];
893 Array.Copy(objectPr.PRindexMap, 0, fixupIndex, 0, objectPr.PRrank);
895 SerTrace.Log( this, "ParseArrayMember RecordArrayElementFixup objectId ",objectPr.PRobjectId," idRef ",pr.PRidRef);
896 m_objectManager.RecordArrayElementFixup(objectPr.PRobjectId, fixupIndex, pr.PRidRef);
900 IndexTraceMessage("ParseArrayMember SetValue ObjectReference "+objectPr.PRnewObj.GetType()+" "+refObj, objectPr.PRindexMap);
901 if (objectPr.PRobjectA != null)
902 objectPr.PRobjectA[objectPr.PRindexMap[0]] = refObj;
904 ((Array)objectPr.PRnewObj).SetValue(refObj, objectPr.PRindexMap); // Object has been instantiated
907 else if (pr.PRmemberValueEnum == InternalMemberValueE.Nested)
909 //Set up dtType for ParseObject
910 SerTrace.Log( this, "ParseArrayMember Nested ");
911 if ((object)pr.PRdtType == null)
913 pr.PRdtType = objectPr.PRarrayElementType;
919 if ((object)objectPr.PRarrayElementType != null) {
920 if ((objectPr.PRarrayElementType.IsValueType) && (pr.PRarrayElementTypeCode == InternalPrimitiveTypeE.Invalid))
923 SerTrace.Log( "ParseArrayMember ValueType ObjectPr ",objectPr.PRnewObj," index ",objectPr.PRmemberIndex);
925 pr.PRisValueTypeFixup = true; //Valuefixup
926 ValueFixupStack.Push(new ValueFixup((Array)objectPr.PRnewObj, objectPr.PRindexMap)); //valuefixup
931 SerTrace.Log( "ParseArrayMember SetValue Nested, memberIndex ",objectPr.PRmemberIndex);
932 IndexTraceMessage("ParseArrayMember SetValue Nested ContainerObject "+objectPr.PRnewObj.GetType()+" "+objectPr.PRnewObj+" item Object "+pr.PRnewObj+" index ", objectPr.PRindexMap);
935 SerTrace.Log( "ParseArrayMember SetValue Nested ContainerObject objectPr ",objectPr.Trace());
936 SerTrace.Log( "ParseArrayMember SetValue Nested ContainerObject pr ",pr.Trace());
938 if (objectPr.PRobjectA != null)
939 objectPr.PRobjectA[objectPr.PRindexMap[0]] = pr.PRnewObj;
941 ((Array)objectPr.PRnewObj).SetValue(pr.PRnewObj, objectPr.PRindexMap);
945 else if (pr.PRmemberValueEnum == InternalMemberValueE.InlineValue)
947 if ((Object.ReferenceEquals(objectPr.PRarrayElementType, Converter.typeofString)) || (Object.ReferenceEquals(pr.PRdtType, Converter.typeofString)))
949 // String in either a string array, or a string element of an object array
950 ParseString(pr, objectPr);
951 IndexTraceMessage("ParseArrayMember SetValue String "+objectPr.PRnewObj.GetType()+" "+pr.PRvalue, objectPr.PRindexMap);
952 if (objectPr.PRobjectA != null)
953 objectPr.PRobjectA[objectPr.PRindexMap[0]] = (Object)pr.PRvalue;
955 ((Array)objectPr.PRnewObj).SetValue((Object)pr.PRvalue, objectPr.PRindexMap);
957 else if (objectPr.PRisArrayVariant)
959 // Array of type object
960 if (pr.PRkeyDt == null)
961 throw new SerializationException(Environment.GetResourceString("Serialization_ArrayTypeObject"));
965 if (Object.ReferenceEquals(pr.PRdtType, Converter.typeofString))
967 ParseString(pr, objectPr);
970 else if (Object.ReferenceEquals(pr.PRdtTypeCode, InternalPrimitiveTypeE.Invalid))
972 CheckSerializable(pr.PRdtType);
973 // Not nested and invalid, so it is an empty object
975 if (IsRemoting && formatterEnums.FEsecurityLevel != TypeFilterLevel.Full)
976 var = FormatterServices.GetSafeUninitializedObject(pr.PRdtType);
979 var = FormatterServices.GetUninitializedObject(pr.PRdtType);
983 if (pr.PRvarValue != null)
986 var = Converter.FromString(pr.PRvalue, pr.PRdtTypeCode);
988 IndexTraceMessage("ParseArrayMember SetValue variant or Object "+objectPr.PRnewObj.GetType()+" var "+var+" indexMap ", objectPr.PRindexMap);
989 if (objectPr.PRobjectA != null)
990 objectPr.PRobjectA[objectPr.PRindexMap[0]] = var;
992 ((Array)objectPr.PRnewObj).SetValue(var, objectPr.PRindexMap); // Primitive type
997 if (objectPr.PRprimitiveArray != null)
999 // Fast path for Soap primitive arrays. Binary was handled in the BinaryParser
1000 objectPr.PRprimitiveArray.SetValue(pr.PRvalue, objectPr.PRindexMap[0]);
1006 if (pr.PRvarValue != null)
1007 var = pr.PRvarValue;
1009 var = Converter.FromString(pr.PRvalue, objectPr.PRarrayElementTypeCode);
1010 SerTrace.Log( this, "ParseArrayMember SetValue Primitive pr.PRvalue "+var," elementTypeCode ",((Enum)objectPr.PRdtTypeCode));
1011 IndexTraceMessage("ParseArrayMember SetValue Primitive "+objectPr.PRnewObj.GetType()+" var: "+var+" varType "+var.GetType(), objectPr.PRindexMap);
1012 if (objectPr.PRobjectA != null)
1014 SerTrace.Log( this, "ParseArrayMember SetValue Primitive predefined array "+objectPr.PRobjectA.GetType());
1015 objectPr.PRobjectA[objectPr.PRindexMap[0]] = var;
1018 ((Array)objectPr.PRnewObj).SetValue(var, objectPr.PRindexMap); // Primitive type
1019 SerTrace.Log( this, "ParseArrayMember SetValue Primitive after");
1023 else if (pr.PRmemberValueEnum == InternalMemberValueE.Null)
1025 SerTrace.Log( "ParseArrayMember Null item ",pr.PRmemberIndex," nullCount ",pr.PRnullCount);
1026 objectPr.PRmemberIndex += pr.PRnullCount-1; //also incremented again below
1029 ParseError(pr, objectPr);
1032 SerTrace.Log( "ParseArrayMember increment memberIndex ",objectPr.PRmemberIndex," ",objectPr.Trace());
1034 objectPr.PRmemberIndex++;
1035 SerTrace.Log( "ParseArrayMember Exit");
1038 [System.Security.SecurityCritical] // auto-generated
1039 private void ParseArrayMemberEnd(ParseRecord pr)
1041 SerTrace.Log( this, "ParseArrayMemberEnd");
1042 // If this is a nested array object, then pop the stack
1043 if (pr.PRmemberValueEnum == InternalMemberValueE.Nested)
1050 // Object member encountered in stream
1051 [System.Security.SecurityCritical] // auto-generated
1052 private void ParseMember(ParseRecord pr)
1054 SerTrace.Log( this, "ParseMember Entry ");
1057 ParseRecord objectPr = (ParseRecord)stack.Peek();
1058 String objName = null;
1059 if (objectPr != null)
1060 objName = objectPr.PRname;
1063 SerTrace.Log( this, "ParseMember ",objectPr.PRobjectId," ",pr.PRname);
1064 SerTrace.Log( this, "ParseMember objectPr ",objectPr.Trace());
1065 SerTrace.Log( this, "ParseMember pr ",pr.Trace());
1067 switch (pr.PRmemberTypeEnum)
1069 case InternalMemberTypeE.Item:
1070 ParseArrayMember(pr);
1072 case InternalMemberTypeE.Field:
1077 //if ((pr.PRdtType == null) && !objectPr.PRobjectInfo.isSi)
1078 if (((object)pr.PRdtType == null) && objectPr.PRobjectInfo.isTyped)
1080 SerTrace.Log( this, "ParseMember pr.PRdtType null and not isSi");
1081 pr.PRdtType = objectPr.PRobjectInfo.GetType(pr.PRname);
1083 if ((object)pr.PRdtType != null)
1084 pr.PRdtTypeCode = Converter.ToCode(pr.PRdtType);
1087 if (pr.PRmemberValueEnum == InternalMemberValueE.Null)
1090 SerTrace.Log( this, "ParseMember null member: ",pr.PRname);
1091 SerTrace.Log( this, "AddValue 1");
1092 objectPr.PRobjectInfo.AddValue(pr.PRname, null, ref objectPr.PRsi, ref objectPr.PRmemberData);
1094 else if (pr.PRmemberValueEnum == InternalMemberValueE.Nested)
1096 SerTrace.Log( this, "ParseMember Nested Type member: ",pr.PRname," objectPr.PRnewObj ",objectPr.PRnewObj);
1099 SerTrace.Log( this, "AddValue 2 ",pr.PRnewObj," is value type ",pr.PRnewObj.GetType().IsValueType);
1101 if ((pr.PRobjectInfo != null) && ((object)pr.PRobjectInfo.objectType != null) && (pr.PRobjectInfo.objectType.IsValueType))
1103 SerTrace.Log( "ParseMember ValueType ObjectPr ",objectPr.PRnewObj," memberName ",pr.PRname," nested object ",pr.PRnewObj);
1104 pr.PRisValueTypeFixup = true; //Valuefixup
1105 ValueFixupStack.Push(new ValueFixup(objectPr.PRnewObj, pr.PRname, objectPr.PRobjectInfo));//valuefixup
1109 SerTrace.Log( this, "AddValue 2A ");
1110 objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRnewObj, ref objectPr.PRsi, ref objectPr.PRmemberData);
1113 else if (pr.PRmemberValueEnum == InternalMemberValueE.Reference)
1115 SerTrace.Log( this, "ParseMember Reference Type member: ",pr.PRname);
1116 // See if object has already been instantiated
1117 Object refObj = m_objectManager.GetObject(pr.PRidRef);
1120 SerTrace.Log( this, "ParseMember RecordFixup: ",pr.PRname);
1121 SerTrace.Log( this, "AddValue 3");
1122 objectPr.PRobjectInfo.AddValue(pr.PRname, null, ref objectPr.PRsi, ref objectPr.PRmemberData);
1123 objectPr.PRobjectInfo.RecordFixup(objectPr.PRobjectId, pr.PRname, pr.PRidRef); // Object not instantiated
1127 SerTrace.Log( this, "ParseMember Referenced Object Known ",pr.PRname," ",refObj);
1128 SerTrace.Log( this, "AddValue 5");
1129 objectPr.PRobjectInfo.AddValue(pr.PRname, refObj, ref objectPr.PRsi, ref objectPr.PRmemberData);
1133 else if (pr.PRmemberValueEnum == InternalMemberValueE.InlineValue)
1135 // Primitive type or String
1136 SerTrace.Log( this, "ParseMember primitive or String member: ",pr.PRname);
1138 if (Object.ReferenceEquals(pr.PRdtType, Converter.typeofString))
1140 ParseString(pr, objectPr);
1141 SerTrace.Log( this, "AddValue 6");
1142 objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRvalue, ref objectPr.PRsi, ref objectPr.PRmemberData);
1144 else if (pr.PRdtTypeCode == InternalPrimitiveTypeE.Invalid)
1146 // The member field was an object put the value is Inline either bin.Base64 or invalid
1147 if (pr.PRarrayTypeEnum == InternalArrayTypeE.Base64)
1149 SerTrace.Log( this, "AddValue 7");
1150 objectPr.PRobjectInfo.AddValue(pr.PRname, Convert.FromBase64String(pr.PRvalue), ref objectPr.PRsi, ref objectPr.PRmemberData);
1152 else if (Object.ReferenceEquals(pr.PRdtType, Converter.typeofObject))
1153 throw new SerializationException(Environment.GetResourceString("Serialization_TypeMissing", pr.PRname));
1156 SerTrace.Log( this, "Object Class with no memberInfo data Member "+pr.PRname+" type "+pr.PRdtType);
1158 ParseString(pr, objectPr); // Register the object if it has an objectId
1159 // Object Class with no memberInfo data
1160 // only special case where AddValue is needed?
1161 if (Object.ReferenceEquals(pr.PRdtType, Converter.typeofSystemVoid))
1163 SerTrace.Log( this, "AddValue 9");
1164 objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRdtType, ref objectPr.PRsi, ref objectPr.PRmemberData);
1166 else if (objectPr.PRobjectInfo.isSi)
1168 // ISerializable are added as strings, the conversion to type is done by the
1169 // ISerializable object
1170 SerTrace.Log( this, "AddValue 10");
1171 objectPr.PRobjectInfo.AddValue(pr.PRname, pr.PRvalue, ref objectPr.PRsi, ref objectPr.PRmemberData);
1178 if (pr.PRvarValue != null)
1179 var = pr.PRvarValue;
1181 var = Converter.FromString(pr.PRvalue, pr.PRdtTypeCode);
1183 // Not a string, convert the value
1184 SerTrace.Log( this, "ParseMember Converting primitive and storing");
1186 SerTrace.Log( this, "ParseMember pr "+pr.Trace());
1187 SerTrace.Log( this, "ParseMember objectPr ",objectPr.Trace());
1189 SerTrace.Log( this, "AddValue 11");
1191 objectPr.PRobjectInfo.AddValue(pr.PRname, var, ref objectPr.PRsi, ref objectPr.PRmemberData);
1195 ParseError(pr, objectPr);
1198 // Object member end encountered in stream
1199 [System.Security.SecurityCritical] // auto-generated
1200 private void ParseMemberEnd(ParseRecord pr)
1202 SerTrace.Log( this, "ParseMemberEnd");
1203 switch (pr.PRmemberTypeEnum)
1205 case InternalMemberTypeE.Item:
1206 ParseArrayMemberEnd(pr);
1208 case InternalMemberTypeE.Field:
1209 if (pr.PRmemberValueEnum == InternalMemberValueE.Nested)
1213 ParseError(pr, (ParseRecord)stack.Peek());
1218 // Processes a string object by getting an internal ID for it and registering it with the objectManager
1219 [System.Security.SecurityCritical] // auto-generated
1220 private void ParseString(ParseRecord pr, ParseRecord parentPr)
1222 SerTrace.Log( this, "ParseString Entry ",pr.PRobjectId," ",pr.PRvalue," ",pr.PRisRegistered);
1223 // Process String class
1224 if ((!pr.PRisRegistered) && (pr.PRobjectId > 0))
1226 SerTrace.Log( this, "ParseString RegisterObject ",pr.PRvalue," ",pr.PRobjectId);
1227 // String is treated as an object if it has an id
1228 //m_objectManager.RegisterObject(pr.PRvalue, pr.PRobjectId);
1229 RegisterObject(pr.PRvalue, pr, parentPr, true);
1234 [System.Security.SecurityCritical] // auto-generated
1235 private void RegisterObject(Object obj, ParseRecord pr, ParseRecord objectPr)
1237 RegisterObject(obj, pr, objectPr, false);
1240 [System.Security.SecurityCritical] // auto-generated
1241 private void RegisterObject(Object obj, ParseRecord pr, ParseRecord objectPr, bool bIsString)
1243 if (!pr.PRisRegistered)
1245 pr.PRisRegistered = true;
1247 SerializationInfo si = null;
1249 MemberInfo memberInfo = null;
1250 int[] indexMap = null;
1252 if (objectPr != null)
1254 indexMap = objectPr.PRindexMap;
1255 parentId = objectPr.PRobjectId;
1257 if (objectPr.PRobjectInfo != null)
1259 if (!objectPr.PRobjectInfo.isSi)
1261 // ParentId is only used if there is a memberInfo
1263 memberInfo = objectPr.PRobjectInfo.GetMemberInfo(pr.PRname);
1267 // SerializationInfo is always needed for ISerialization
1270 SerTrace.Log( this, "RegisterObject 0bj ",obj," objectId ",pr.PRobjectId," si ", si," parentId ",parentId," memberInfo ",memberInfo, " indexMap "+indexMap);
1272 m_objectManager.RegisterString((String)obj, pr.PRobjectId, si, parentId, memberInfo);
1274 m_objectManager.RegisterObject(obj, pr.PRobjectId, si, parentId, memberInfo, indexMap);
1279 // Assigns an internal ID associated with the binary id number
1281 // Older formatters generate ids for valuetypes using a different counter than ref types. Newer ones use
1282 // a single counter, only value types have a negative value. Need a way to handle older formats.
1283 private const int THRESHOLD_FOR_VALUETYPE_IDS = Int32.MaxValue;
1284 private bool bOldFormatDetected = false;
1285 private IntSizedArray valTypeObjectIdTable;
1287 [System.Security.SecurityCritical] // auto-generated
1288 internal long GetId(long objectId)
1291 if (!bFullDeserialization)
1292 InitFullDeserialization();
1298 if (bOldFormatDetected || objectId == -1)
1300 // Alarm bells. This is an old format. Deal with it.
1301 bOldFormatDetected = true;
1302 if (valTypeObjectIdTable == null)
1303 valTypeObjectIdTable = new IntSizedArray();
1306 if ((tempObjId = valTypeObjectIdTable[(int)objectId]) == 0)
1308 tempObjId = THRESHOLD_FOR_VALUETYPE_IDS + objectId;
1309 valTypeObjectIdTable[(int)objectId] = (int)tempObjId;
1313 return -1 * objectId;
1317 // Trace which includes a single dimensional int array
1318 [Conditional("SER_LOGGING")]
1319 private void IndexTraceMessage(String message, int[] index)
1321 StringBuilder sb = StringBuilderCache.Acquire(10);
1323 for (int i=0; i<index.Length; i++)
1325 sb.Append(index[i]);
1326 if (i != index.Length -1)
1330 SerTrace.Log( this, message," ", StringBuilderCache.GetStringAndRelease(sb));
1333 [System.Security.SecurityCritical] // auto-generated
1334 internal Type Bind(String assemblyString, String typeString)
1337 if (m_binder != null)
1338 type = m_binder.BindToType(assemblyString, typeString);
1339 if ((object)type == null)
1340 type= FastBindToType(assemblyString, typeString);
1345 internal class TypeNAssembly
1348 public String assemblyName;
1351 NameCache typeCache = new NameCache();
1352 [System.Security.SecurityCritical] // auto-generated
1353 internal Type FastBindToType(String assemblyName, String typeName)
1357 TypeNAssembly entry = (TypeNAssembly)typeCache.GetCachedValue(typeName);
1359 if (entry == null || entry.assemblyName != assemblyName)
1361 Assembly assm = null;
1362 if (bSimpleAssembly)
1365 #if !DISABLE_CAS_USE
1366 sfileIOPermission.Assert();
1370 assm = ObjectReader.ResolveSimpleAssemblyName(new AssemblyName(assemblyName));
1371 #else // FEATURE_FUSION
1372 Assembly.Load(assemblyName);
1373 #endif // FEATURE_FUSION
1376 #if !DISABLE_CAS_USE
1377 CodeAccessPermission.RevertAssert();
1382 SerTrace.Log( this, "FastBindTypeType ",e.ToString());
1388 ObjectReader.GetSimplyNamedTypeFromAssembly(assm, typeName, ref type);
1393 #if !DISABLE_CAS_USE
1394 sfileIOPermission.Assert();
1397 assm = Assembly.Load(assemblyName);
1400 #if !DISABLE_CAS_USE
1401 CodeAccessPermission.RevertAssert();
1407 SerTrace.Log( this, "FastBindTypeType ",e.ToString());
1413 type = FormatterServices.GetTypeFromAssembly(assm, typeName);
1416 if ((object)type == null)
1419 // before adding it to cache, let us do the security check
1420 CheckTypeForwardedTo(assm, type.Assembly, type);
1422 entry = new TypeNAssembly();
1424 entry.assemblyName = assemblyName;
1425 typeCache.SetCachedValue(entry);
1430 [System.Security.SecurityCritical] // auto-generated
1431 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
1432 private static Assembly ResolveSimpleAssemblyName(AssemblyName assemblyName)
1434 StackCrawlMark stackMark = StackCrawlMark.LookForMe;
1435 Assembly assm = RuntimeAssembly.LoadWithPartialNameInternal(assemblyName, null, ref stackMark);
1436 if (assm == null && assemblyName != null)
1437 assm = RuntimeAssembly.LoadWithPartialNameInternal(assemblyName.Name, null, ref stackMark);
1441 [System.Security.SecurityCritical] // auto-generated
1442 private static void GetSimplyNamedTypeFromAssembly(Assembly assm, string typeName, ref Type type)
1444 // Catching any exceptions that could be thrown from a failure on assembly load
1445 // This is necessary, for example, if there are generic parameters that are qualified with a version of the assembly that predates the one available
1448 type = FormatterServices.GetTypeFromAssembly(assm, typeName);
1450 catch (TypeLoadException) { }
1451 catch (FileNotFoundException) { }
1452 catch (FileLoadException) { }
1453 catch (BadImageFormatException) { }
1455 if ((object)type == null)
1457 type = Type.GetType(typeName, ObjectReader.ResolveSimpleAssemblyName, new TopLevelAssemblyTypeResolver(assm).ResolveType, false /* throwOnError */);
1462 private String previousAssemblyString;
1463 private String previousName;
1464 private Type previousType;
1467 [System.Security.SecurityCritical] // auto-generated
1468 internal Type GetType(BinaryAssemblyInfo assemblyInfo, String name)
1470 Type objectType = null;
1472 if (((previousName != null) && (previousName.Length == name.Length) && (previousName.Equals(name))) &&
1473 ((previousAssemblyString != null) && (previousAssemblyString.Length == assemblyInfo.assemblyString.Length) &&(previousAssemblyString.Equals(assemblyInfo.assemblyString))))
1475 objectType = previousType;
1476 //Console.WriteLine("Hit "+(++hit)+" "+objectType);
1480 objectType = Bind(assemblyInfo.assemblyString, name);
1481 if ((object)objectType == null)
1483 Assembly sourceAssembly = assemblyInfo.GetAssembly();
1485 if (bSimpleAssembly)
1487 ObjectReader.GetSimplyNamedTypeFromAssembly(sourceAssembly, name, ref objectType);
1491 objectType = FormatterServices.GetTypeFromAssembly(sourceAssembly, name);
1494 // here let us do the security check
1495 if (objectType != null)
1497 CheckTypeForwardedTo(sourceAssembly, objectType.Assembly, objectType);
1501 previousAssemblyString = assemblyInfo.assemblyString;
1502 previousName = name;
1503 previousType = objectType;
1505 //Console.WriteLine("name "+name+" assembly "+assemblyInfo.assemblyString+" objectType "+objectType);
1509 [SecuritySafeCritical]
1510 private static void CheckTypeForwardedTo(Assembly sourceAssembly, Assembly destAssembly, Type resolvedType)
1512 if ( !FormatterServices.UnsafeTypeForwardersIsEnabled() && sourceAssembly != destAssembly )
1514 // we have a type forward to attribute !
1515 #if !DISABLE_CAS_USE
1516 // we can try to see if the dest assembly has less permissionSet
1517 if (!destAssembly.PermissionSet.IsSubsetOf(sourceAssembly.PermissionSet))
1520 // let us try to see if typeforwardedfrom is there
1522 // let us hit the cache first
1523 TypeInformation typeInfo = BinaryFormatter.GetTypeInformation(resolvedType);
1524 if (typeInfo.HasTypeForwardedFrom)
1526 Assembly typeFowardedFromAssembly = null;
1529 // if this Assembly.Load failed, we still want to throw security exception
1530 typeFowardedFromAssembly = Assembly.Load(typeInfo.AssemblyString);
1533 #if !DISABLE_CAS_USE
1534 if (typeFowardedFromAssembly != sourceAssembly)
1536 // throw security exception
1537 throw new SecurityException() { Demanded = sourceAssembly.PermissionSet };
1543 #if !DISABLE_CAS_USE
1544 // throw security exception
1545 throw new SecurityException() { Demanded = sourceAssembly.PermissionSet };
1552 internal sealed class TopLevelAssemblyTypeResolver
1554 private Assembly m_topLevelAssembly;
1556 public TopLevelAssemblyTypeResolver(Assembly topLevelAssembly)
1558 m_topLevelAssembly = topLevelAssembly;
1561 public Type ResolveType(Assembly assembly, string simpleTypeName, bool ignoreCase)
1563 if (assembly == null)
1564 assembly = m_topLevelAssembly;
1566 return assembly.GetType(simpleTypeName, false, ignoreCase);