Bug fix. While reading the Cecil source I realized that array bounds are signed.

This commit is contained in:
jfrijters 2012-10-13 21:48:36 +00:00
Родитель 739a077efa
Коммит 2080556174
3 изменённых файлов: 68 добавлений и 3 удалений

Просмотреть файл

@ -100,6 +100,29 @@ namespace IKVM.Reflection.Reader
}
}
internal int ReadCompressedInt()
{
byte b1 = PeekByte();
int value = ReadCompressedUInt();
if ((value & 1) == 0)
{
return value >> 1;
}
else
{
switch (b1 & 0xC0)
{
case 0:
case 0x40:
return (value >> 1) - 0x40;
case 0x80:
return (value >> 1) - 0x2000;
default:
return (value >> 1) - 0x10000000;
}
}
}
internal string ReadString()
{
if (PeekByte() == 0xFF)

Просмотреть файл

@ -155,7 +155,7 @@ namespace IKVM.Reflection
return args;
}
private static int[] ReadArrayBounds(ByteReader br)
private static int[] ReadArraySizes(ByteReader br)
{
int num = br.ReadCompressedUInt();
if (num == 0)
@ -170,6 +170,21 @@ namespace IKVM.Reflection
return arr;
}
private static int[] ReadArrayBounds(ByteReader br)
{
int num = br.ReadCompressedUInt();
if (num == 0)
{
return null;
}
int[] arr = new int[num];
for (int i = 0; i < num; i++)
{
arr[i] = br.ReadCompressedInt();
}
return arr;
}
private static Type ReadTypeOrVoid(ModuleReader module, ByteReader br, IGenericContext context)
{
if (br.PeekByte() == ELEMENT_TYPE_VOID)
@ -236,7 +251,7 @@ namespace IKVM.Reflection
return ReadType(module, br, context).__MakeArrayType(mods);
case ELEMENT_TYPE_ARRAY:
mods = CustomModifiers.Read(module, br, context);
return ReadType(module, br, context).__MakeArrayType(br.ReadCompressedUInt(), ReadArrayBounds(br), ReadArrayBounds(br), mods);
return ReadType(module, br, context).__MakeArrayType(br.ReadCompressedUInt(), ReadArraySizes(br), ReadArrayBounds(br), mods);
case ELEMENT_TYPE_PTR:
mods = CustomModifiers.Read(module, br, context);
return ReadTypeOrVoid(module, br, context).__MakePointerType(mods);
@ -347,7 +362,7 @@ namespace IKVM.Reflection
bb.WriteCompressedUInt(lobounds.Length);
for (int i = 0; i < lobounds.Length; i++)
{
bb.WriteCompressedUInt(lobounds[i]);
bb.WriteCompressedInt(lobounds[i]);
}
return;
}

Просмотреть файл

@ -229,6 +229,33 @@ namespace IKVM.Reflection.Writer
}
}
internal void WriteCompressedInt(int value)
{
if (value >= 0)
{
WriteCompressedUInt(value << 1);
}
else if (value >= -64)
{
value = ((value << 1) & 0x7F) | 1;
Write((byte)value);
}
else if (value >= -8192)
{
value = ((value << 1) & 0x3FFF) | 1;
Write((byte)(0x80 | (value >> 8)));
Write((byte)value);
}
else
{
value = ((value << 1) & 0x1FFFFFFF) | 1;
Write((byte)(0xC0 | (value >> 24)));
Write((byte)(value >> 16));
Write((byte)(value >> 8));
Write((byte)value);
}
}
internal void Write(ByteBuffer bb)
{
if (pos + bb.Length > buffer.Length)