summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Resources/ResourceReader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Resources/ResourceReader.cs')
-rw-r--r--src/mscorlib/src/System/Resources/ResourceReader.cs251
1 files changed, 4 insertions, 247 deletions
diff --git a/src/mscorlib/src/System/Resources/ResourceReader.cs b/src/mscorlib/src/System/Resources/ResourceReader.cs
index 89cfdb1b9f..d752771020 100644
--- a/src/mscorlib/src/System/Resources/ResourceReader.cs
+++ b/src/mscorlib/src/System/Resources/ResourceReader.cs
@@ -20,13 +20,7 @@ namespace System.Resources {
using System.Text;
using System.Collections;
using System.Collections.Generic;
-#if FEATURE_SERIALIZATION
- using System.Runtime.Serialization;
- using System.Runtime.Serialization.Formatters;
- using System.Runtime.Serialization.Formatters.Binary;
-#endif // FEATURE_SERIALIZATION
using System.Reflection;
- using System.Security.Permissions;
using System.Security;
using System.Globalization;
using System.Configuration.Assemblies;
@@ -73,7 +67,6 @@ namespace System.Resources {
}
- [System.Runtime.InteropServices.ComVisible(true)]
public sealed class ResourceReader : IResourceReader
{
// A reasonable default buffer size for reading from files, especially
@@ -100,9 +93,6 @@ namespace System.Resources {
private unsafe int* _namePositionsPtr; // If we're using UnmanagedMemoryStream
private RuntimeType[] _typeTable; // Lazy array of Types for resource values.
private int[] _typeNamePositions; // To delay initialize type table
-#if FEATURE_SERIALIZATION
- private BinaryFormatter _objFormatter; // Deserialization stuff.
-#endif // FEATURE_SERIALIZATION
private int _numResources; // Num of resources files, in case arrays aren't allocated.
// We'll include a separate code path that uses UnmanagedMemoryStream to
@@ -116,45 +106,11 @@ namespace System.Resources {
private bool _debug; // Whether this file has debugging stuff in it.
#endif
-#if FEATURE_SERIALIZATION
- private bool[] _safeToDeserialize; // Whether to assert serialization permission
- private TypeLimitingDeserializationBinder _typeLimitingBinder;
-
- // One of our goals is to make sure localizable Windows Forms apps
- // work in semi-trusted scenarios (ie, without serialization permission).
- // Unfortunate we're serializing out some complex types that currently
- // require a security check on deserialization. We may fix this
- // in a next version, but for now just hard-code a list.
- // Hard-code in the assembly name (minus version) so people can't spoof us.
- private static readonly String[] TypesSafeForDeserialization = {
- "System.String[], mscorlib, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.DateTime[], mscorlib, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Drawing.Bitmap, System.Drawing, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Drawing.Imaging.Metafile, System.Drawing, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Drawing.Point, System.Drawing, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Drawing.PointF, System.Drawing, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Drawing.Size, System.Drawing, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Drawing.SizeF, System.Drawing, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Drawing.Font, System.Drawing, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Drawing.Icon, System.Drawing, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Drawing.Color, System.Drawing, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
- "System.Windows.Forms.Cursor, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken,
- "System.Windows.Forms.Padding, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken,
- "System.Windows.Forms.LinkArea, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken,
- "System.Windows.Forms.ImageListStreamer, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken,
- "System.Windows.Forms.ListViewGroup, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken,
- "System.Windows.Forms.ListViewItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken,
- "System.Windows.Forms.ListViewItem+ListViewSubItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken,
- "System.Windows.Forms.ListViewItem+ListViewSubItem+SubItemStyle, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken,
- "System.Windows.Forms.OwnerDrawPropertyBag, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken,
- "System.Windows.Forms.TreeNode, System.Windows.Forms, Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken
- };
-#endif // FEATURE_SERIALIZATION
public ResourceReader(String fileName)
{
_resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default);
- _store = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.RandomAccess, Path.GetFileName(fileName), false), Encoding.UTF8);
+ _store = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.RandomAccess), Encoding.UTF8);
BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(String). UnmanagedMemoryStream: "+(_ums!=null));
try {
@@ -240,10 +196,6 @@ namespace System.Resources {
// Unaligned, little endian format
return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
}
-
- private void SkipInt32() {
- _store.BaseStream.Seek(4, SeekOrigin.Current);
- }
private void SkipString() {
@@ -580,8 +532,6 @@ namespace System.Resources {
}
}
-#if FEATURE_SERIALIZATION
-#endif
private Object _LoadObjectV1(int pos) {
_store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin);
int typeIndex = _store.Read7BitEncodedInt();
@@ -629,11 +579,7 @@ namespace System.Resources {
return new Decimal(bits);
}
else {
-#if FEATURE_SERIALIZATION
- return DeserializeObject(typeIndex);
-#else
throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization"));
-#endif // FEATURE_SERIALIZATION
}
}
@@ -759,7 +705,7 @@ namespace System.Resources {
// For the case that we've memory mapped in the .resources
// file, just return a Stream pointing to that block of memory.
unsafe {
- return new UnmanagedMemoryStream(_ums.PositionPointer, len, len, FileAccess.Read, true);
+ return new UnmanagedMemoryStream(_ums.PositionPointer, len, len, FileAccess.Read);
}
}
@@ -771,57 +717,10 @@ namespace System.Resources {
}
// Normal serialized objects
-#if FEATURE_SERIALIZATION
- int typeIndex = typeCode - ResourceTypeCode.StartOfUserTypes;
- return DeserializeObject(typeIndex);
-#else
throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization"));
-#endif // FEATURE_SERIALIZATION
}
-#if FEATURE_SERIALIZATION
- // Helper method to safely deserialize a type, using a type-limiting
- // deserialization binder to simulate a type-limiting deserializer.
- // This method handles types that are safe to deserialize, as well as
- // ensuring we only get back what we expect.
- private Object DeserializeObject(int typeIndex)
- {
- RuntimeType type = FindType(typeIndex);
- // Initialize deserialization permission array, if needed
- if (_safeToDeserialize == null)
- InitSafeToDeserializeArray();
-
- // Ensure that the object we deserialized is exactly the same
- // type of object we thought we should be deserializing. This
- // will help prevent malformed .resources files from using our
- // serialization permission assert to deserialize anything
- // via a malformed type ID.
-
- Object graph;
- if (_safeToDeserialize[typeIndex]) {
- // Don't assert serialization permission - just ask the binary
- // formatter to avoid a permission check. This ensures that any
- // types which do demand serialization permission in their
- // deserialization .cctors will fail.
- // Also, use a serialization binder to limit bind requests to
- // our allowed list of WinForms types.
- _objFormatter.Binder = _typeLimitingBinder;
- _typeLimitingBinder.ExpectingToDeserialize(type);
- graph = _objFormatter.UnsafeDeserialize(_store.BaseStream, null);
- }
- else {
- _objFormatter.Binder = null;
- graph = _objFormatter.Deserialize(_store.BaseStream);
- }
-
- // This check is about correctness, not security at this point.
- if (graph.GetType() != type)
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResType&SerBlobMismatch", type.FullName, graph.GetType().FullName));
-
- return graph;
- }
-#endif // FEATURE_SERIALIZATION
// Reads in the header information for a .resources file. Verifies some
// of the assumptions about this resource set, and builds the class table
@@ -829,12 +728,6 @@ namespace System.Resources {
private void ReadResources()
{
Debug.Assert(_store != null, "ResourceReader is closed!");
-#if FEATURE_SERIALIZATION
- BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence));
- _typeLimitingBinder = new TypeLimitingDeserializationBinder();
- bf.Binder = _typeLimitingBinder;
- _objFormatter = bf;
-#endif // FEATURE_SERIALIZATION
try {
// mega try-catch performs exceptionally bad on x64; factored out body into
@@ -918,7 +811,7 @@ namespace System.Resources {
throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
}
BCLDebug.Log("RESMGRFILEFORMAT", "ReadResources: Expecting " + _numResources + " resources.");
-#if _DEBUG
+#if RESOURCE_FILE_FORMAT_DEBUG
if (ResourceManager.DEBUG >= 4)
Console.WriteLine("ResourceReader::ReadResources - Reading in "+_numResources+" resources");
#endif
@@ -938,7 +831,7 @@ namespace System.Resources {
SkipString();
}
-#if _DEBUG
+#if RESOURCE_FILE_FORMAT_DEBUG
if (ResourceManager.DEBUG >= 5)
Console.WriteLine("ResourceReader::ReadResources - Reading in "+numTypes+" type table entries");
#endif
@@ -1049,7 +942,6 @@ namespace System.Resources {
String typeName = _store.ReadString();
_typeTable[typeIndex] = (RuntimeType)Type.GetType(typeName, true);
}
-#if !FEATURE_SERIALIZATION
// If serialization isn't supported, we convert FileNotFoundException to
// NotSupportedException for consistency with v2. This is a corner-case, but the
// idea is that we want to give the user a more accurate error message. Even if
@@ -1064,7 +956,6 @@ namespace System.Resources {
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization"));
}
-#endif // FEATURE_SERIALIZATION
finally {
_store.BaseStream.Position = oldPos;
}
@@ -1073,74 +964,6 @@ namespace System.Resources {
return _typeTable[typeIndex];
}
-#if FEATURE_SERIALIZATION
- private void InitSafeToDeserializeArray()
- {
- _safeToDeserialize = new bool[_typeTable.Length];
- for(int i=0; i<_typeTable.Length; i++) {
- long oldPos = _store.BaseStream.Position;
- String typeName;
- try {
- _store.BaseStream.Position = _typeNamePositions[i];
- typeName = _store.ReadString();
- }
- finally {
- _store.BaseStream.Position = oldPos;
- }
-
- AssemblyName an;
- String typePart;
- RuntimeType resourceType = (RuntimeType)Type.GetType(typeName, false);
- if (resourceType == null) {
- an = null;
- typePart = typeName;
- }
- else {
- // Enums should be safe to deserialize, and this helps out
- // partially trusted, localized WinForms apps.
- if (resourceType.BaseType == typeof(Enum)) {
- _safeToDeserialize[i] = true;
- continue;
- }
-
- // For most types, check our TypesSafeForDeserialization.
- typePart = resourceType.FullName;
-
- an = new AssemblyName();
-
- // resourceType is retrieved via Type.GetType and must be a RuntimeType
- RuntimeAssembly a = (RuntimeAssembly)resourceType.Assembly;
- an.Init(a.GetSimpleName(),
- a.GetPublicKey(),
- null, // public key token
- null, // version
- a.GetLocale(),
- AssemblyHashAlgorithm.None,
- AssemblyVersionCompatibility.SameMachine,
- null, // codebase
- AssemblyNameFlags.PublicKey,
- null); // strong name key pair
- }
-
- foreach(String safeType in TypesSafeForDeserialization) {
- if (ResourceManager.CompareNames(safeType, typePart, an)) {
-#if _DEBUG
- if (ResourceManager.DEBUG >= 7)
- Console.WriteLine("ResReader: Found a type-safe type to deserialize! Type name: {0}", typeName);
-#endif
- _safeToDeserialize[i] = true;
- continue;
- }
- }
-
-#if _DEBUG
- if (ResourceManager.DEBUG >= 7)
- if (!_safeToDeserialize[i])
- Console.WriteLine("ResReader: Found a type that wasn't safe to deserialize: {0}", typeName);
-#endif
- }
- }
-#endif // FEATURE_SERIALIZATION
public void GetResourceData(String resourceName, out String resourceType, out byte[] resourceData)
{
@@ -1224,72 +1047,6 @@ namespace System.Resources {
}
}
-#if FEATURE_SERIALIZATION
- // We need to build a type-limiting deserializer. We know exactly which
- // type we want to deserialize, and if someone tells us we have type X
- // (which might be safe to deserialize) and they give us a serialized
- // form of type Y, we don't want to run the deserialization constructor
- // because we've asserted serialization formatter permission. Instead,
- // limit the binary formatter's type binding to precisely the type we
- // expect. If they ever don't match, that's a corrupt .resources file.
- // We also must check the complete object graph to ensure all of the
- // graph contains safe objects.
- // Note this is tightly coupled to the BinaryFormatter, since we use
- // its internal ObjectReader::FastBindToType method, and we had to
- // change the ObjectReader to register itself with this type.
- internal sealed class TypeLimitingDeserializationBinder : SerializationBinder
- {
- private RuntimeType _typeToDeserialize;
- // This is tightly coupled with the binary formatter, because we
- // want to use exactly the same code found in the ObjectReader
- // to do the lookup, then just give a thumbs up or down based on
- // a type equality comparison. In the future, we could consider
- // some better refactoring of this code.
- private ObjectReader _objectReader;
-
- internal ObjectReader ObjectReader {
- get { return _objectReader; }
- set { _objectReader = value; }
- }
-
- internal void ExpectingToDeserialize(RuntimeType type)
- {
- _typeToDeserialize = type;
- }
-
- public override Type BindToType(string assemblyName, string typeName)
- {
- // BinaryObjectReader::Bind tries us first, then its own code.
- // Returning null means let the default binding rules happen.
- AssemblyName an = new AssemblyName(assemblyName);
-
- bool safe = false;
- foreach(String safeType in TypesSafeForDeserialization) {
- if (ResourceManager.CompareNames(safeType, typeName, an)) {
- safe = true;
- break;
- }
- }
-
- // WinForms types may internally use some enums that aren't
- // on our safe to deserialize list, like Font using FontStyle.
- Type t = ObjectReader.FastBindToType(assemblyName, typeName);
- if (t.IsEnum)
- safe = true;
-
- if (safe)
- return null;
-
- // Throw instead of returning null.
- // If you're looking at this in a debugger, you've either
- // got a malformed .resources file on your hands, or WinForms
- // types have taken a new dependency on another type. Check
- // whether assemblyName & typeName refer to a trustworthy type,
- // & consider adding it to the TypesSafeToDeserialize list.
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResType&SerBlobMismatch", _typeToDeserialize.FullName, typeName));
- }
- }
-#endif // FEATURE_SERIALIZATION
internal sealed class ResourceEnumerator : IDictionaryEnumerator