@@ -28,7 +28,7 @@ use std::fmt::{Debug, Formatter};
28
28
use std:: sync:: Arc ;
29
29
30
30
use crate :: writer:: DictionaryTracker ;
31
- use crate :: { size_prefixed_root_as_message , KeyValue , Message , CONTINUATION_MARKER } ;
31
+ use crate :: { KeyValue , Message , CONTINUATION_MARKER } ;
32
32
use DataType :: * ;
33
33
34
34
/// Low level Arrow [Schema] to IPC bytes converter
@@ -255,32 +255,43 @@ pub fn try_schema_from_ipc_buffer(buffer: &[u8]) -> Result<Schema, ArrowError> {
255
255
// 4 bytes - an optional IPC_CONTINUATION_TOKEN prefix
256
256
// 4 bytes - the byte length of the payload
257
257
// a flatbuffer Message whose header is the Schema
258
- if buffer. len ( ) >= 4 {
259
- // check continuation marker
260
- let continuation_marker = & buffer[ 0 ..4 ] ;
261
- let begin_offset: usize = if continuation_marker. eq ( & CONTINUATION_MARKER ) {
262
- // 4 bytes: CONTINUATION_MARKER
263
- // 4 bytes: length
264
- // buffer
265
- 4
266
- } else {
267
- // backward compatibility for buffer without the continuation marker
268
- // 4 bytes: length
269
- // buffer
270
- 0
271
- } ;
272
- let msg = size_prefixed_root_as_message ( & buffer[ begin_offset..] ) . map_err ( |err| {
273
- ArrowError :: ParseError ( format ! ( "Unable to convert flight info to a message: {err}" ) )
274
- } ) ?;
275
- let ipc_schema = msg. header_as_schema ( ) . ok_or_else ( || {
276
- ArrowError :: ParseError ( "Unable to convert flight info to a schema" . to_string ( ) )
277
- } ) ?;
278
- Ok ( fb_to_schema ( ipc_schema) )
279
- } else {
280
- Err ( ArrowError :: ParseError (
258
+ if buffer. len ( ) < 4 {
259
+ return Err ( ArrowError :: ParseError (
281
260
"The buffer length is less than 4 and missing the continuation marker or length of buffer" . to_string ( )
282
- ) )
261
+ ) ) ;
262
+ }
263
+
264
+ let ( len, buffer) = if buffer[ ..4 ] == CONTINUATION_MARKER {
265
+ if buffer. len ( ) < 8 {
266
+ return Err ( ArrowError :: ParseError (
267
+ "The buffer length is less than 8 and missing the length of buffer" . to_string ( ) ,
268
+ ) ) ;
269
+ }
270
+ buffer[ 4 ..] . split_at ( 4 )
271
+ } else {
272
+ buffer. split_at ( 4 )
273
+ } ;
274
+
275
+ let len = <i32 >:: from_le_bytes ( len. try_into ( ) . unwrap ( ) ) ;
276
+ if len < 0 {
277
+ return Err ( ArrowError :: ParseError ( format ! (
278
+ "The encapsulated message's reported length is negative ({len})"
279
+ ) ) ) ;
280
+ }
281
+
282
+ if buffer. len ( ) < len as usize {
283
+ let actual_len = buffer. len ( ) ;
284
+ return Err ( ArrowError :: ParseError (
285
+ format ! ( "The buffer length ({actual_len}) is less than the encapsulated message's reported length ({len})" )
286
+ ) ) ;
283
287
}
288
+
289
+ let msg = crate :: root_as_message ( buffer)
290
+ . map_err ( |err| ArrowError :: ParseError ( format ! ( "Unable to get root as message: {err:?}" ) ) ) ?;
291
+ let ipc_schema = msg. header_as_schema ( ) . ok_or_else ( || {
292
+ ArrowError :: ParseError ( "Unable to convert flight info to a schema" . to_string ( ) )
293
+ } ) ?;
294
+ Ok ( fb_to_schema ( ipc_schema) )
284
295
}
285
296
286
297
/// Get the Arrow data type from the flatbuffer Field table
0 commit comments