{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/1001","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/1001/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/1001/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/1001/events","html_url":"https://github.com/dotnet/corefx/issues/1001","id":58666316,"number":1001,"title":"MetadataReader overuses uint","user":{"login":"nguerrera","id":75470,"avatar_url":"https://avatars.githubusercontent.com/u/75470?v=3","gravatar_id":"","url":"https://api.github.com/users/nguerrera","html_url":"https://github.com/nguerrera","followers_url":"https://api.github.com/users/nguerrera/followers","following_url":"https://api.github.com/users/nguerrera/following{/other_user}","gists_url":"https://api.github.com/users/nguerrera/gists{/gist_id}","starred_url":"https://api.github.com/users/nguerrera/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nguerrera/subscriptions","organizations_url":"https://api.github.com/users/nguerrera/orgs","repos_url":"https://api.github.com/users/nguerrera/repos","events_url":"https://api.github.com/users/nguerrera/events{/privacy}","received_events_url":"https://api.github.com/users/nguerrera/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dotnet/corefx/labels/0%20-%20Backlog","name":"0 - Backlog","color":"CCCCCC"},{"url":"https://api.github.com/repos/dotnet/corefx/labels/up%20for%20grabs","name":"up for grabs","color":"159818"}],"state":"open","locked":false,"assignee":{"login":"nguerrera","id":75470,"avatar_url":"https://avatars.githubusercontent.com/u/75470?v=3","gravatar_id":"","url":"https://api.github.com/users/nguerrera","html_url":"https://github.com/nguerrera","followers_url":"https://api.github.com/users/nguerrera/followers","following_url":"https://api.github.com/users/nguerrera/following{/other_user}","gists_url":"https://api.github.com/users/nguerrera/gists{/gist_id}","starred_url":"https://api.github.com/users/nguerrera/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nguerrera/subscriptions","organizations_url":"https://api.github.com/users/nguerrera/orgs","repos_url":"https://api.github.com/users/nguerrera/repos","events_url":"https://api.github.com/users/nguerrera/events{/privacy}","received_events_url":"https://api.github.com/users/nguerrera/received_events","type":"User","site_admin":false},"milestone":null,"comments":1,"created_at":"2015-02-23T23:17:12Z","updated_at":"2015-03-22T02:10:14Z","closed_at":null,"body":"This was sent to me from @tmat, quote:\r\n\r\n>We should so something about all the int <-> uint casts in the reader – some of them are actual bugs or questionable behaviors, since we shouldn’t be throwing overflow exceptions.\r\n>\r\n>(found the following by looking for “internal uint” in Tables.cs)\r\n\r\n```C#\r\nTypeDefinition.GetLayout() \r\n{ \r\n   … \r\n   // here we overflow:\r\n   int size = (int)reader.ClassLayoutTable.GetClassSize(classLayoutRowId);\r\n   … \r\n}\r\n\r\n/// Returns field layout offset, or -1 if not available.      \r\nFieldDefinition.GetOffset()\r\n{\r\n\r\n    uint layoutRowId = reader.FieldLayoutTable.FindFieldLayoutRowId(Handle);\r\n    if (layoutRowId == 0)\r\n    {\r\n        return -1;\r\n    }\r\n\r\n    uint offset = reader.FieldLayoutTable.GetOffset(layoutRowId);\r\n\r\n    // we reinterpret too big (but strictly speaking not invalid) values:\r\n    if (offset > int.MaxValue)\r\n    {\r\n        // CLI spec says:\r\n\r\n        // \"Offset (a 4-byte constant)\"\r\n        // \"Offset shall be zero or more\"\r\n        // \r\n        // Peverify fails with \"Type load failed\" error if offset is greater than Int32.MaxValue.\r\n        return -1;\r\n    }\r\n \r\n    return (int)offset;\r\n}\r\n\r\nint ExportedTypeExtensions.GetTypeDefinitionId\r\n{\r\n   // here we overflow:\r\n   return (int)exportedType.reader.ExportedTypeTable.GetTypeDefId(exportedType.rowId);\r\n}\r\n\r\ninternal void GetMethodRange(\r\n    TypeDefinitionHandle typeDef,\r\n    out int firstMethodRowId, \r\n    out int lastMethodRowId)\r\n{\r\n   uint typeDefRowId = typeDef.RowId;\r\n\r\n   // here we overflow:\r\n   firstMethodRowId = (int)this.TypeDefTable.GetMethodStart(typeDefRowId);\r\n   …\r\n}\r\n```\r\n\r\n\r\n>We should probably check the range and throw BadImageFormat when passing the value out thru public API to be consistent – we’re already doing that for handles in MemoryBlock.PeekReference:\r\n\r\n>if (!TokenTypeIds.IsValidRowId(value)) ThrowReferenceOverflow();\r\n\r\n>Internally “rowId” fields of handles should probably be ints, not uints since we assert: Debug.Assert(TokenTypeIds.IsValidRowId(rowId)) \r\n\r\n>“token” fields of heap handles should stay uints since we use all the bits.\r\n\r\n>Once we change the rowId to int and apply the type transitively I think we should be able to get rid of most uints.\r\n\r\nHe also shared the following implementation suggestion:\r\n>Currently we have\r\n\r\n \r\n```C#\r\ninternal Int32 PeekInt32(int offset)\r\n{\r\n    CheckBounds(offset, sizeof(Int32));\r\n    return *(Int32*)(Pointer + offset);\r\n}\r\n\r\ninternal UInt32 PeekUInt32(int offset)\r\n{\r\n     CheckBounds(offset, sizeof(UInt32));\r\n     return *(UInt32*)(Pointer + offset);}\r\n}\r\n```\r\n \r\n> on MemoryBlock. What about \r\n\r\n```C#\r\ninternal uint PeekUnsignedInt32(int offset)\r\n{\r\n    CheckBounds(offset, sizeof(uint));\r\n    return *(uint*)(Pointer + offset);\r\n}\r\n\r\ninternal int PeekSignedInt32(int offset)\r\n{\r\n    CheckBounds(offset, sizeof(int));\r\n    return *(int*)(Pointer + offset);\r\n}\r\n\r\ninternal int PeekInt32(int offset)\r\n{\r\n    CheckBounds(offset, sizeof(int));\r\n    var result = *(int*)(Pointer + offset);\r\n    if (result < 0) Throw();\r\n    return result;\r\n}\r\n````\r\n\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/84494151","html_url":"https://github.com/dotnet/corefx/issues/1001#issuecomment-84494151","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/1001","id":84494151,"user":{"login":"talebi","id":2081646,"avatar_url":"https://avatars.githubusercontent.com/u/2081646?v=3","gravatar_id":"","url":"https://api.github.com/users/talebi","html_url":"https://github.com/talebi","followers_url":"https://api.github.com/users/talebi/followers","following_url":"https://api.github.com/users/talebi/following{/other_user}","gists_url":"https://api.github.com/users/talebi/gists{/gist_id}","starred_url":"https://api.github.com/users/talebi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/talebi/subscriptions","organizations_url":"https://api.github.com/users/talebi/orgs","repos_url":"https://api.github.com/users/talebi/repos","events_url":"https://api.github.com/users/talebi/events{/privacy}","received_events_url":"https://api.github.com/users/talebi/received_events","type":"User","site_admin":false},"created_at":"2015-03-22T02:10:14Z","updated_at":"2015-03-22T02:10:14Z","body":"no sure if its related but when I add a reference to Autodesk Revit 2013/2015 to a project I get a compile error in (VS 2015 CTP):\r\nMetadata file 'E:\\dev\\cadtools_revit\\Source\\Lib\\RevitAPI\\RevitAPI_x64_2013.dll' could not be opened -- Row ID or heap offset is too large.\r\n"}}