Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cifti/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,13 @@ if(NIFTI_BUILD_TESTING AND NIFTI_BUILD_APPLICATIONS)
-eval_cext -eval_type show_summary )
set_tests_properties( ${TEST_PREFIX}_tool_unterminated_cext
PROPERTIES PASS_REGULAR_EXPRESSION "MapName : demo" )

# Nesting past AXML_MAX_DEPTH must stay inside the skip block rather than
# walk off the fixed stack; the regex pins that the rest still parses.
add_test( NAME ${TEST_PREFIX}_deep_nesting
COMMAND $<TARGET_FILE:${NIFTI_PACKAGE_PREFIX}cifti_tool>
-as_cext -eval_cext -eval_type show_summary
-input ${CMAKE_CURRENT_LIST_DIR}/testdata/deep_nesting.xml )
set_tests_properties( ${TEST_PREFIX}_deep_nesting
PROPERTIES PASS_REGULAR_EXPRESSION "BrainModel" )
endif()
27 changes: 21 additions & 6 deletions cifti/afni_xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,9 @@ static int epush(afni_xml_control * xd, const char * ename, const char ** attr)
if( xd->verb > 3 ) show_attrs(xd, attr, 1);
}

/* determine whether we should go into a skip block */
if( errs ) xd->dskip = xd->depth;
/* determine whether we should go into a skip block; keep the outermost
such depth, since that is the one whose pop ends the skip */
if( errs && ! xd->dskip ) xd->dskip = xd->depth;

/* if we are in a skip block, do nothing but monitor stack */
if( xd->dskip ) {
Expand Down Expand Up @@ -767,16 +768,16 @@ static int epop(afni_xml_control * xd, const char * ename)
if( xd->wkeep ) xd->wkeep = 0; /* clear storage continuation */

if( xd->dskip ) {
if( xd->dskip == xd->depth ) xd->dskip = 0; /* clear */

if( xd->verb > 3 )
fprintf(stderr,"-- skip=%d, depth=%d, skipping pop element '%s'\n",
xd->dskip, xd->depth, ename);

/* clear only after the element has been skipped, so that the stack
is not touched at a depth that was never pushed onto it */
if( xd->dskip == xd->depth ) xd->dskip = 0;
} else {
process_popped_element(xd, ename);
}

if( ! xd->dskip ) {
xd->stack[xd->depth-1] = NULL; /* should be irrelevant */

if( xd->verb > 4 ) {
Expand All @@ -793,7 +794,21 @@ static int epop(afni_xml_control * xd, const char * ename)
static int process_popped_element(afni_xml_control * xd, const char * ename)
{
afni_xml_t * ax;

/* a stack slot is filled by the matching epush(). An element that was
skipped never fills one, so do not assume this slot holds a struct
with a name. */
if( xd->depth <= 0 || xd->depth > AXML_MAX_DEPTH ) {
if( gAXD.verb ) fprintf(stderr,"** pop at depth %d!\n", xd->depth);
return 1;
}

ax = xd->stack[xd->depth-1];
if( ! ax || ! ax->name ) {
if( gAXD.verb ) fprintf(stderr,"** pop of unfilled element '%s'!\n",
ename ? ename : "NULL");
return 1;
}

if( strcmp(ename, ax->name) ) {
if( gAXD.verb ) fprintf(stderr,"** pop mismatch!\n");
Expand Down
8 changes: 8 additions & 0 deletions cifti/testdata/deep_nesting.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<CIFTI Version="2">
<Matrix>
<MatrixIndicesMap AppliesToMatrixDimension="0" IndicesMapToDataType="CIFTI_INDEX_TYPE_BRAIN_MODELS">
<BrainModel IndexOffset="0" IndexCount="1" ModelType="CIFTI_MODEL_TYPE_VOXELS"/>
<deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep><deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep></deep>
</MatrixIndicesMap>
</Matrix>
</CIFTI>
Loading