nexusformat / code

NeXus API code and helper applications
GNU Lesser General Public License v2.1
12 stars 16 forks source link

Long filenames cause NXopen to produce a seg fault #434

Closed samueljackson92 closed 8 years ago

samueljackson92 commented 8 years ago

We got a bug report in Mantid (mantidproject/mantid#16146) that was caused by attempting to save a workspace with an excessively long name to file (longer than the system limits). Turns out this appears to cause the nexus library (or HDF5) to seg fault instead of passing back an error code. This was observed on both Debian and OSX, but presumably affects Windows as well.

Here's some simple code to reproduce the problem based of off one of the tests in this repo:

#include <stdio.h>
#include <stdlib.h>
#include <napi.h>

#define ON_ERROR(msgstr)\
{\
    fprintf(stderr,msgstr);\
    return 1;\
}

int main (int argc, char* argv[])
{
    NXaccess access_mode = NXACC_CREATE5;
    // this works
    //const char* szFile = "leak_test1.nxs";
    // this gives a seg fault
    const char* szFile = "bh28000019_van_ar27630120leer_sfleer_scaled_bh28_Van-300K_with-all-corr_sfdata_group_bh28_Van-300K_with-all-corr_vana_coefs_2theta-11.56_bh28_Van-300K_with-all-corr_sfdata_group_vanacorr_bh28000020_van_ar27630121leer_nsfleer_scaled_bh28_Van-300K_with-all-corr_nsfdata_group_bh28_Van-300K_with-all-corr_vana_coefs_2theta-11.56_bh28_Van-300K_with-all-corr_nsfdata_group_vanacorr_ar27630060nicr_ar27630061nicr_ar27630120leer_sfleer_scaled_ar27630121leer_nsfleer_scaled_bh28_Van-300K_with-all-corr_nsf_data_nicrcorr";

    NXhandle fileid;

    if (NXopen(szFile, access_mode, &fileid) != NX_OK) 
        ON_ERROR("NXopen failed!\n")

    if( NXclose(&fileid) != NX_OK)
        ON_ERROR("NXclose failed!\n")

    printf("File write was successful!\n");
    fileid = NULL;
    return 0;
}

This should fall over in the NX5open call. I also tested this with using the access mode NXACC_CREATE and I get the same result.

mkoennecke commented 8 years ago

This does not die any more but returns with an error message. This is all what needs to be done here.