Validate the magic bytes and get the length of the full footer.
| 488 | |
| 489 | // Validate the magic bytes and get the length of the full footer. |
| 490 | uint32_t ParseFooterLength(const std::shared_ptr<::arrow::Buffer>& footer_buffer, |
| 491 | const int64_t footer_read_size) { |
| 492 | // Check if all bytes are read. Check if last 4 bytes read have the magic bits |
| 493 | if (footer_buffer->size() != footer_read_size || |
| 494 | (memcmp(footer_buffer->data() + footer_read_size - 4, kParquetMagic, 4) != 0 && |
| 495 | memcmp(footer_buffer->data() + footer_read_size - 4, kParquetEMagic, 4) != 0)) { |
| 496 | throw ParquetInvalidOrCorruptedFileException( |
| 497 | "Parquet magic bytes not found in footer. Either the file is corrupted or this " |
| 498 | "is not a parquet file."); |
| 499 | } |
| 500 | // Both encrypted/unencrypted footers have the same footer length check. |
| 501 | uint32_t metadata_len = |
| 502 | ::arrow::bit_util::FromLittleEndian(::arrow::util::SafeLoadAs<uint32_t>( |
| 503 | reinterpret_cast<const uint8_t*>(footer_buffer->data()) + footer_read_size - |
| 504 | kFooterSize)); |
| 505 | if (metadata_len > source_size_ - kFooterSize) { |
| 506 | throw ParquetInvalidOrCorruptedFileException( |
| 507 | "Parquet file size is ", source_size_, |
| 508 | " bytes, smaller than the size reported by footer's (", metadata_len, "bytes)"); |
| 509 | } |
| 510 | return metadata_len; |
| 511 | } |
| 512 | |
| 513 | // Does not throw. |
| 514 | Future<> ParseMetaDataAsync() { |
nothing calls this directly
no test coverage detected