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++;