@@ -73,37 +73,49 @@ getClusterReader(const Reader& zimReader, offset_t offset, Cluster::Compression*
7373
7474} // unnamed namespace
7575
76- std::shared_ptr<Cluster> Cluster::read (const Reader& zimReader, offset_t clusterOffset)
76+ std::shared_ptr<Cluster> Cluster::read (const Reader& zimReader, offset_t clusterOffset, size_t maxBlobCount )
7777 {
7878 Compression comp;
7979 bool extended;
8080 auto reader = getClusterReader (zimReader, clusterOffset, &comp, &extended);
81- return std::make_shared<Cluster>(std::move (reader), comp, extended);
81+ return std::make_shared<Cluster>(std::move (reader), comp, extended, maxBlobCount );
8282 }
8383
84- Cluster::Cluster (std::unique_ptr<IStreamReader> reader_, Compression comp, bool isExtended)
84+ Cluster::Cluster (std::unique_ptr<IStreamReader> reader_, Compression comp, bool isExtended, size_t maxBlobCount )
8585 : compression(comp),
8686 isExtended (isExtended),
8787 m_reader(std::move(reader_))
8888 {
8989 if (isExtended) {
90- read_header<uint64_t >();
90+ read_header<uint64_t >(maxBlobCount );
9191 } else {
92- read_header<uint32_t >();
92+ read_header<uint32_t >(maxBlobCount );
9393 }
9494 }
9595
9696 Cluster::~Cluster () = default ;
9797
9898 /* This return the number of char read */
9999 template <typename OFFSET_TYPE>
100- void Cluster::read_header ()
100+ void Cluster::read_header (size_t maxBlobCount )
101101 {
102102 // read first offset, which specifies, how many offsets we need to read
103103 OFFSET_TYPE offset = m_reader->read <OFFSET_TYPE>();
104104
105+ if ( offset < 2 * sizeof (OFFSET_TYPE) ) {
106+ throw zim::ZimFileFormatError (" Error parsing cluster. Offset of the first blob is too small." );
107+ }
108+
105109 size_t n_offset = offset / sizeof (OFFSET_TYPE);
106110
111+ if ( n_offset * sizeof (OFFSET_TYPE) != offset ) {
112+ throw zim::ZimFileFormatError (" Error parsing cluster. Offset of the first blob is not properly aligned." );
113+ }
114+
115+ if ( n_offset > maxBlobCount + 1 ) {
116+ throw zim::ZimFileFormatError (" Error parsing cluster. Offset of the first blob is too large." );
117+ }
118+
107119 // read offsets
108120 m_blobOffsets.clear ();
109121 m_blobOffsets.reserve (n_offset);
0 commit comments