Skip to content

Commit a0ffed7

Browse files
committed
Fix hdf5 file position bug when handling indirect blocks
Keep track of file position when recursing into readIndirectBlock. Fixes #1546
1 parent 2eb5091 commit a0ffed7

2 files changed

Lines changed: 73 additions & 2 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright (c) 2026 University Corporation for Atmospheric Research/Unidata
3+
* See LICENSE for license information.
4+
*/
5+
6+
package ucar.nc2.iosp.hdf5;
7+
8+
import static com.google.common.truth.Truth.assertThat;
9+
import static ucar.unidata.util.test.TestDir.cdmUnitTestDir;
10+
11+
import java.io.IOException;
12+
import java.util.List;
13+
import org.junit.Test;
14+
import org.junit.experimental.categories.Category;
15+
import ucar.nc2.Group;
16+
import ucar.nc2.NetcdfFile;
17+
import ucar.nc2.NetcdfFiles;
18+
import ucar.nc2.Variable;
19+
import ucar.unidata.util.test.category.NeedsCdmUnitTest;
20+
21+
@Category(NeedsCdmUnitTest.class)
22+
public class TestH5IndirectBlocks {
23+
24+
private final String h5FileWithIndirectBlocks = cdmUnitTestDir + "formats/hdf5/bitplane_imaris/indirect_blocks.ims";
25+
26+
// demonstrated https://github.com/Unidata/netcdf-java/issues/1546 using old api
27+
@Test
28+
public void testOpenFileWithIndirectBlocksOldApi() throws IOException {
29+
NetcdfFile ncf = NetcdfFile.open(h5FileWithIndirectBlocks);
30+
assertThat(ncf).isNotNull();
31+
}
32+
33+
// demonstrated https://github.com/Unidata/netcdf-java/issues/1546 using new api
34+
@Test
35+
public void testOpenFileWithIndirectBlocksNewApi() throws IOException {
36+
NetcdfFile ncf = NetcdfFiles.open(h5FileWithIndirectBlocks);
37+
assertThat(ncf).isNotNull();
38+
}
39+
40+
@Test
41+
public void testReadIndirectBlocksOldApi() throws IOException {
42+
NetcdfFile ncf = NetcdfFile.open(h5FileWithIndirectBlocks);
43+
assertThat(ncf).isNotNull();
44+
readVariableWithIndirectBlocks(ncf);
45+
}
46+
47+
@Test
48+
public void testReadIndirectBlocksNewApi() throws IOException {
49+
NetcdfFile ncf = NetcdfFiles.open(h5FileWithIndirectBlocks);
50+
assertThat(ncf).isNotNull();
51+
readVariableWithIndirectBlocks(ncf);
52+
}
53+
54+
private void readVariableWithIndirectBlocks(NetcdfFile ncf) throws IOException {
55+
Group groupWithIndirectBlocksVariables = ncf.findGroup("/DataSetInfo/ZeissAttrs");
56+
assertThat(groupWithIndirectBlocksVariables).isNotNull();
57+
List<Variable> variablesWithIndirectBlocks = groupWithIndirectBlocksVariables.getVariables();
58+
assertThat(variablesWithIndirectBlocks).isNotNull();
59+
assertThat(variablesWithIndirectBlocks.size()).isEqualTo(3);
60+
for (Variable variable : variablesWithIndirectBlocks) {
61+
String data = variable.readScalarString();
62+
assertThat(data).isNotNull();
63+
assertThat(data).isNotEmpty();
64+
assertThat(data).startsWith("<?xml");
65+
assertThat(data).contains("<ArrayOfRt");
66+
}
67+
}
68+
}

cdm/core/src/main/java/ucar/nc2/iosp/hdf5/FractalHeap.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata
2+
* Copyright (c) 1998-2026 John Caron and University Corporation for Atmospheric Research/Unidata
33
* See LICENSE for license information.
44
*/
55

@@ -513,8 +513,11 @@ void readIndirectBlock(IndirectBlock iblock, long pos, long heapAddress, boolean
513513
long childIndirectAddress = h5.readOffset();
514514
if (debugDetail || debugFractalHeap)
515515
debugOut.println(" InDirectChild " + row + " address= " + childIndirectAddress);
516-
if (childIndirectAddress >= 0)
516+
if (childIndirectAddress >= 0) {
517+
long savePos = raf.getFilePointer();
517518
readIndirectBlock(iblock2, childIndirectAddress, heapAddress, hasFilter);
519+
raf.seek(savePos);
520+
}
518521
}
519522
}
520523

0 commit comments

Comments
 (0)