diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000001.gdbtable b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000001.gdbtable new file mode 100644 index 000000000000..b8df547eda91 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000001.gdbtable differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000001.gdbtablx b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000001.gdbtablx new file mode 100644 index 000000000000..8327f75cb45c Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000001.gdbtablx differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000002.gdbtable b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000002.gdbtable new file mode 100644 index 000000000000..06f10eaf022b Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000002.gdbtable differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000002.gdbtablx b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000002.gdbtablx new file mode 100644 index 000000000000..b17fb6b96e25 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000002.gdbtablx differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000003.gdbtable b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000003.gdbtable new file mode 100644 index 000000000000..00c610703fc6 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000003.gdbtable differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000003.gdbtablx b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000003.gdbtablx new file mode 100644 index 000000000000..aa8412769fe3 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000003.gdbtablx differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000004.gdbtable b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000004.gdbtable new file mode 100644 index 000000000000..9d1da5583650 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000004.gdbtable differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000004.gdbtablx b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000004.gdbtablx new file mode 100644 index 000000000000..6a69871ab4e6 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000004.gdbtablx differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000005.gdbtable b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000005.gdbtable new file mode 100644 index 000000000000..75dac36be0a4 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000005.gdbtable differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000005.gdbtablx b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000005.gdbtablx new file mode 100644 index 000000000000..a9e25586862f Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000005.gdbtablx differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000006.gdbtable b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000006.gdbtable new file mode 100644 index 000000000000..87825c3173e2 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000006.gdbtable differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000006.gdbtablx b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000006.gdbtablx new file mode 100644 index 000000000000..ab7baaec612b Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000006.gdbtablx differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000007.gdbtable b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000007.gdbtable new file mode 100644 index 000000000000..29fcd156792c Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000007.gdbtable differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000007.gdbtablx b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000007.gdbtablx new file mode 100644 index 000000000000..f639905039c5 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000007.gdbtablx differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000009.gdbindexes b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000009.gdbindexes new file mode 100644 index 000000000000..6b351b6ac2bb Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000009.gdbindexes differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000009.gdbtable b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000009.gdbtable new file mode 100644 index 000000000000..eafc4284e360 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000009.gdbtable differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000009.gdbtablx b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000009.gdbtablx new file mode 100644 index 000000000000..2cae1126c73f Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/a00000009.gdbtablx differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/gdb b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/gdb new file mode 100644 index 000000000000..506f9c628294 Binary files /dev/null and b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/gdb differ diff --git a/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/timestamps b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/timestamps new file mode 100644 index 000000000000..05d2b9440ec0 --- /dev/null +++ b/autotest/ogr/data/filegdb/corrupted_gdbindexes.gdb/timestamps @@ -0,0 +1 @@ +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/autotest/ogr/ogr_openfilegdb.py b/autotest/ogr/ogr_openfilegdb.py index da4e529509f2..e93bb7789f95 100755 --- a/autotest/ogr/ogr_openfilegdb.py +++ b/autotest/ogr/ogr_openfilegdb.py @@ -2942,3 +2942,19 @@ def test_ogr_openfilegdb_arc_interior_point_bug_line(): f, "MULTILINESTRING ((37252520.1717 7431529.9154,38549084.9654 758964.7573))", ) + + +############################################################################### +# Test https://github.com/OSGeo/gdal/issues/11295 where .gdbindexes contains +# entry with unusual (corrupted ? disabled?) entries + + +def test_ogr_openfilegdb_weird_gdbindexes(): + + # File a00000009.gdbindexes has been replaced by file a00000029.gdbindexes + # from attachment of https://github.com/OSGeo/gdal/issues/11295#issuecomment-2491158506 + with ogr.Open("data/filegdb/corrupted_gdbindexes.gdb") as ds: + lyr = ds.GetLayer(0) + lyr.SetAttributeFilter("id = '1'") + f = lyr.GetNextFeature() + assert f diff --git a/ogr/ogrsf_frmts/openfilegdb/filegdbtable.cpp b/ogr/ogrsf_frmts/openfilegdb/filegdbtable.cpp index ca13652339e5..49596c6b2fe7 100644 --- a/ogr/ogrsf_frmts/openfilegdb/filegdbtable.cpp +++ b/ogr/ogrsf_frmts/openfilegdb/filegdbtable.cpp @@ -2537,6 +2537,7 @@ int FileGDBTable::GetIndexCount() CPLDebug("OpenFileGDB", ".gdbindexes v9 not handled yet"); return 0; } + returnErrorAndCleanupIf(nIndexCount >= static_cast(GetFieldCount() + 1) * 10, VSIFree(pabyIdx)); @@ -2547,7 +2548,7 @@ int FileGDBTable::GetIndexCount() returnErrorAndCleanupIf(static_cast(pabyEnd - pabyCur) < sizeof(GUInt32), VSIFree(pabyIdx)); - GUInt32 nIdxNameCarCount = GetUInt32(pabyCur, 0); + const GUInt32 nIdxNameCarCount = GetUInt32(pabyCur, 0); pabyCur += sizeof(GUInt32); returnErrorAndCleanupIf(nIdxNameCarCount > 1024, VSIFree(pabyIdx)); returnErrorAndCleanupIf(static_cast(pabyEnd - pabyCur) < @@ -2557,13 +2558,56 @@ int FileGDBTable::GetIndexCount() ReadUTF16String(pabyCur, nIdxNameCarCount)); pabyCur += 2 * nIdxNameCarCount; + // 4 "magic fields" + returnErrorAndCleanupIf(static_cast(pabyEnd - pabyCur) < + sizeof(GUInt16) + sizeof(GUInt32) + + sizeof(GUInt16) + sizeof(GUInt32), + VSIFree(pabyIdx)); + // const GUInt16 nMagic1 = GetUInt16(pabyCur, 0); + const GUInt32 nMagic2 = GetUInt32(pabyCur + sizeof(GUInt16), 0); + const GUInt16 nMagic3 = + GetUInt16(pabyCur + sizeof(GUInt16) + sizeof(GUInt32), 0); + if (!((nMagic2 == 2 && nMagic3 == 0) || + (nMagic2 == 4 && nMagic3 == 0) || + (nMagic2 == 16 && nMagic3 == 65535))) + { + // Cf files a00000029.gdbindexes, a000000ea.gdbindexes, a000000ed.gdbindexes, + // a000000f8.gdbindexes, a000000fb.gdbindexes, a00000103.gdbindexes + // from https://github.com/OSGeo/gdal/issues/11295#issuecomment-2491158506 + CPLDebug("OpenFileGDB", "Reading %s", pszIndexesName); + CPLDebug( + "OpenFileGDB", + "Strange (deleted?) index descriptor at index %u of name %s", i, + osIndexName.c_str()); + + // Skip magic fields + pabyCur += sizeof(GUInt16); + + const GUInt32 nColNameCarCount = nMagic2; + pabyCur += sizeof(GUInt32); + returnErrorAndCleanupIf(nColNameCarCount > 1024, VSIFree(pabyIdx)); + returnErrorAndCleanupIf(static_cast(pabyEnd - pabyCur) < + 2 * nColNameCarCount, + VSIFree(pabyIdx)); + pabyCur += 2 * nColNameCarCount; + + // Skip magic field + returnErrorAndCleanupIf(static_cast(pabyEnd - pabyCur) < + sizeof(GUInt16), + VSIFree(pabyIdx)); + pabyCur += sizeof(GUInt16); + + continue; + } + // Skip magic fields - pabyCur += 2 + 4 + 2 + 4; + pabyCur += sizeof(GUInt16) + sizeof(GUInt32) + sizeof(GUInt16) + + sizeof(GUInt32); returnErrorAndCleanupIf(static_cast(pabyEnd - pabyCur) < sizeof(GUInt32), VSIFree(pabyIdx)); - GUInt32 nColNameCarCount = GetUInt32(pabyCur, 0); + const GUInt32 nColNameCarCount = GetUInt32(pabyCur, 0); pabyCur += sizeof(GUInt32); returnErrorAndCleanupIf(nColNameCarCount > 1024, VSIFree(pabyIdx)); returnErrorAndCleanupIf(static_cast(pabyEnd - pabyCur) < @@ -2574,7 +2618,10 @@ int FileGDBTable::GetIndexCount() pabyCur += 2 * nColNameCarCount; // Skip magic field - pabyCur += 2; + returnErrorAndCleanupIf(static_cast(pabyEnd - pabyCur) < + sizeof(GUInt16), + VSIFree(pabyIdx)); + pabyCur += sizeof(GUInt16); auto poIndex = std::make_unique(); poIndex->m_osIndexName = osIndexName;