Skip to content

Commit dcb7202

Browse files
Handling of out-of-bound access in a cluster
The test ZIM file invalid.too_small_offset_of_first_blob_in_cluster_4.zim which simulated a corrupted cluster header leading to a cluster with no blobs in it (a case which was decriminalized by the previous commit) now caught a situation where a crash could occur because of an out-of-bound access in a cluster (this can happen due to invalid data in either a cluster header or a dirent). Cluster::getBlobOffset() must be checked at runtime too!
1 parent af24841 commit dcb7202

File tree

3 files changed

+17
-3
lines changed

3 files changed

+17
-3
lines changed

src/cluster.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,25 @@ getClusterReader(const Reader& zimReader, offset_t offset, Cluster::Compression*
137137
}
138138
}
139139

140-
zsize_t Cluster::getBlobSize(blob_index_t n) const
140+
void Cluster::checkBlobIndex(blob_index_t n) const
141141
{
142142
if (blob_index_type(n)+1 >= m_blobOffsets.size()) {
143143
throw ZimFileFormatError("blob index out of range");
144144
}
145+
}
146+
147+
zsize_t Cluster::getBlobSize(blob_index_t n) const
148+
{
149+
checkBlobIndex(n);
145150
return zsize_t(m_blobOffsets[blob_index_type(n)+1].v - m_blobOffsets[blob_index_type(n)].v);
146151
}
147152

153+
offset_t Cluster::getBlobOffset(blob_index_t n) const
154+
{
155+
checkBlobIndex(n);
156+
return offset_t(1) + m_blobOffsets[blob_index_type(n)];
157+
}
158+
148159
const Reader& Cluster::getReader(blob_index_t n) const
149160
{
150161
std::lock_guard<std::mutex> lock(m_readerAccessMutex);

src/cluster.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ namespace zim
7676
void read_header(size_t maxBlobCount);
7777
const Reader& getReader(blob_index_t n) const;
7878

79+
void checkBlobIndex(blob_index_t n) const;
80+
7981
public:
8082
Cluster(std::unique_ptr<IStreamReader> reader, Compression comp, bool isExtended, size_t maxBlobCount);
8183
~Cluster();
@@ -86,7 +88,8 @@ namespace zim
8688

8789
zsize_t getBlobSize(blob_index_t n) const;
8890

89-
offset_t getBlobOffset(blob_index_t n) const { return offset_t(1) + m_blobOffsets[blob_index_type(n)]; }
91+
offset_t getBlobOffset(blob_index_t n) const;
92+
9093
Blob getBlob(blob_index_t n) const;
9194
Blob getBlob(blob_index_t n, offset_t offset, zsize_t size) const;
9295

test/archive.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ TEST_F(ZimArchive, validate)
798798

799799
TEST_BROKEN_ZIM_NAME(
800800
"invalid.too_small_offset_of_first_blob_in_cluster_4.zim",
801-
"Error parsing cluster. Offset of the first blob is too small.\n"
801+
"blob index out of range\n"
802802
)
803803

804804
TEST_BROKEN_ZIM_NAME(

0 commit comments

Comments
 (0)