2525 */
2626
2727using System ;
28+ using System . Buffers ;
2829using System . IO ;
2930using System . IO . Compression ;
30- using OpenMetaverse ;
3131using OpenMetaverse . StructuredData ;
3232
3333namespace OpenMetaverse . Assets
@@ -79,22 +79,38 @@ public override bool Decode()
7979
8080 foreach ( string partName in header . Keys )
8181 {
82- if ( header [ partName ] . Type != OSDType . Map )
82+ OSD partOSD = header [ partName ] ;
83+ if ( partOSD is not OSDMap partInfo )
8384 {
84- MeshData [ partName ] = header [ partName ] ;
85+ MeshData [ partName ] = partOSD ;
8586 continue ;
8687 }
8788
88- OSDMap partInfo = ( OSDMap ) header [ partName ] ;
89- if ( partInfo [ "offset" ] < 0 || partInfo [ "size" ] == 0 )
89+ if ( ! partInfo . TryGetInt ( "offset" , out int partDataOffset ) )
9090 {
9191 MeshData [ partName ] = partInfo ;
9292 continue ;
9393 }
9494
95- byte [ ] part = new byte [ partInfo [ "size" ] ] ;
96- Buffer . BlockCopy ( AssetData , partInfo [ "offset" ] + ( int ) start , part , 0 , part . Length ) ;
97- MeshData [ partName ] = DecompressMeshOSD ( part ) ;
95+ partDataOffset += ( int ) start ;
96+ if ( partDataOffset > AssetData . Length )
97+ {
98+ MeshData [ partName ] = partInfo ;
99+ continue ;
100+ }
101+
102+ if ( ! partInfo . TryGetInt ( "size" , out int partDataSize ) )
103+ {
104+ MeshData [ partName ] = partInfo ;
105+ continue ;
106+ }
107+ if ( partDataOffset + partDataSize > AssetData . Length )
108+ {
109+ MeshData [ partName ] = partInfo ;
110+ continue ;
111+ }
112+
113+ MeshData [ partName ] = DecompressMeshOSD ( AssetData , partDataOffset , partDataSize ) ;
98114 }
99115 }
100116 return true ;
@@ -106,34 +122,50 @@ public override bool Decode()
106122 }
107123 }
108124
109- public static OSD DecompressMeshOSD ( byte [ ] data )
125+ public static OSD DecodeBlock ( byte [ ] MeshBytes , string BlockName )
110126 {
111- OSD decodedOsd = null ;
112-
113- using ( MemoryStream inMs = new MemoryStream ( data ) )
127+ try
114128 {
115- using ( MemoryStream outMs = new MemoryStream ( ) )
116- {
117- using ( DeflateStream decompressionStream = new DeflateStream ( inMs , CompressionMode . Decompress ) )
118- {
119- byte [ ] readBuffer = new byte [ 2048 ] ;
120- inMs . Read ( readBuffer , 0 , 2 ) ; // skip first 2 bytes in header
121- int readLen = 0 ;
129+ using MemoryStream data = new ( MeshBytes ) ;
122130
123- while ( ( readLen = decompressionStream . Read ( readBuffer , 0 , readBuffer . Length ) ) > 0 )
124- outMs . Write ( readBuffer , 0 , readLen ) ;
131+ OSDMap header = ( OSDMap ) OSDParser . DeserializeLLSDBinary ( data ) ;
132+ long start = data . Position ;
125133
126- outMs . Flush ( ) ;
134+ if ( ! header . TryGetOSDMap ( BlockName , out OSDMap LayerInfo ) )
135+ return null ;
127136
128- outMs . Seek ( 0 , SeekOrigin . Begin ) ;
137+ if ( ! LayerInfo . TryGetInt ( "offset" , out int BlockDataOffset ) )
138+ return null ;
129139
130- byte [ ] decompressedBuf = outMs . GetBuffer ( ) ;
140+ BlockDataOffset += ( int ) start ;
141+ if ( BlockDataOffset > MeshBytes . Length )
142+ return null ;
131143
132- decodedOsd = OSDParser . DeserializeLLSDBinary ( decompressedBuf ) ;
133- }
134- }
144+ if ( ! LayerInfo . TryGetInt ( "size" , out int BlockDataSize ) )
145+ return null ;
146+
147+ if ( BlockDataOffset + BlockDataSize > MeshBytes . Length )
148+ return null ;
149+
150+ return DecompressMeshOSD ( MeshBytes , BlockDataOffset , BlockDataSize ) ;
151+ }
152+ catch ( Exception ex )
153+ {
154+ Logger . Log ( "Failed to decode mesh asset" , Helpers . LogLevel . Error , ex ) ;
155+ return null ;
156+ }
157+ }
158+
159+ public static OSD DecompressMeshOSD ( byte [ ] data , int start , int len )
160+ {
161+ using MemoryStream outMs = new ( 4 * len ) ;
162+ using ( MemoryStream inMs = new ( data , start + 2 , len - 2 ) ) // skip first 2 bytes
163+ {
164+ using DeflateStream decompressionStream = new ( inMs , CompressionMode . Decompress ) ;
165+ decompressionStream . CopyTo ( outMs ) ;
135166 }
136- return decodedOsd ;
167+ outMs . Seek ( 0 , SeekOrigin . Begin ) ;
168+ return OSDParser . DeserializeLLSDBinary ( outMs ) ;
137169 }
138170 }
139171}
0 commit comments