diff --git a/cifti/CMakeLists.txt b/cifti/CMakeLists.txt
index ef43a4e4..405d87d8 100644
--- a/cifti/CMakeLists.txt
+++ b/cifti/CMakeLists.txt
@@ -51,6 +51,26 @@ if(NIFTI_BUILD_TESTING AND NIFTI_BUILD_APPLICATIONS)
PROPERTIES PASS_REGULAR_EXPRESSION "demo"
FAIL_REGULAR_EXPRESSION "no CIFTI extension" )
+ # A read failure must be reported, not taken for the end of the document.
+ # The input is a directory, which opens on POSIX and fails at the first
+ # read; Windows refuses the open instead, so there is no read to fail.
+ if( NOT WIN32 )
+ add_test( NAME ${TEST_PREFIX}_xml_read_error
+ COMMAND $
+ -input ${CMAKE_CURRENT_LIST_DIR}/testdata )
+ set_tests_properties( ${TEST_PREFIX}_xml_read_error
+ PROPERTIES PASS_REGULAR_EXPRESSION "failed to read XML file" )
+ endif()
+
+ # A readable document must still parse, and must not report a read error.
+ add_test( NAME ${TEST_PREFIX}_xml_read_ok
+ COMMAND $
+ -input ${CMAKE_CURRENT_LIST_DIR}/testdata/mim_known_child.xml
+ -verb 2 )
+ set_tests_properties( ${TEST_PREFIX}_xml_read_ok
+ PROPERTIES PASS_REGULAR_EXPRESSION "xlist read"
+ FAIL_REGULAR_EXPRESSION "failed to read XML file" )
+
# An extension payload that fills esize-8 with no NUL must not be read
# past its end; the regex pins that the payload is still parsed.
add_test( NAME ${TEST_PREFIX}_tool_unterminated_cext
diff --git a/cifti/afni_xml.c b/cifti/afni_xml.c
index 5a92738a..8e55a485 100644
--- a/cifti/afni_xml.c
+++ b/cifti/afni_xml.c
@@ -197,6 +197,10 @@ afni_xml_list axml_read_file(const char * fname, int read_data)
if( reset_xml_buf(xd, &buf, &bsize) ) break;
blen = (unsigned)fread(buf, 1, (size_t)bsize, fp);
+ if( ferror(fp) ) {
+ fprintf(stderr,"** failed to read XML file '%s'\n", fname);
+ break;
+ }
/* check for early termination */
bshort = loc_strnlen(buf, blen);
@@ -207,7 +211,9 @@ afni_xml_list axml_read_file(const char * fname, int read_data)
blen = (unsigned)bshort;
}
- done = blen < (unsigned) bsize;
+ /* feof() also stops a file ending exactly on a buffer boundary,
+ sparing a final read that can only return zero */
+ done = blen < (unsigned) bsize || feof(fp);
if(xd->verb > 4) fprintf(stderr,"-- XML_Parse # %d\n", pcount);
pcount++;