/* This is part of the netCDF package. Copyright 2018 University Corporation for Atmospheric Research/Unidata. See COPYRIGHT file for conditions of use. This is a very simple example which tests rejection of bad names for netCDF data objects, including names with "/" character, trailing spaces, leading special characters, and invalid UTF-8 strings. $Id: tst_names.c 2792 2014-10-27 06:02:59Z wkliao $ */ #include #include #include #include #include #ifdef USE_PARALLEL #include #endif #include #include "err_macros.h" /* The data file we will create. */ #define FILE_NAME "tst_names.nc" #define NDIMS 1 #define DIMLEN 1 #define ERROR {printf("Error at line %d: %s\n",__LINE__,nc_strerror(res)); nerrs++; continue;} #define ERRORI {printf("Error at line %d (loop=%d): %s\n",__LINE__,i,nc_strerror(res)); nerrs++; continue;} int main(int argc, char **argv) { char *valid[] = { /* pressure in 23 languages */ "\xd8\xa7\xd9\x84\xd8\xb6\xd8\xba\xd8\xb7", "\xd0\xbd\xd0\xb0\xd0\xbb\xd1\x8f\xd0\xb3\xd0\xb0\xd0\xbd\xd0\xb5", "\xe5\x8e\x8b\xe5\x8a\x9b", "\xe5\xa3\x93\xe5\x8a\x9b", "pritisak", "tlaku", "pres", "druk", "pressure", "paine", "pression", "Druck", "\xcf\x80\xce\xaf\xce\xb5\xcf\x83\xce\xb7", "\xe0\xa4\xa6\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb5", "pressione", "\xe5\x9c\xa7\xe5\x8a\x9b", "\xec\x95\x95\xeb\xa0\xa5", "press", "ci\xc5\x9bnienie", "Press\xc3\xa3o", "presiune", "\xd0\xb4\xd0\xb0\xd0\xb2\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5", "presi\xc3\xb3n", /* special characters in names, numeric characters at the start of names */ "has blank", "has:colon", "a", "A", "0leading_numeric_char", "1", "0x123" }; char *notvalid[] = { "-leading_special_char", "trailing_space ", "trailing_tab\t", "trailing_newline\n", "has_control_char_\a_in_name", "has ascii_del_\x7f_in name", /* Invalid UTF-8 of various sorts, thanks to Markus Kuhn */ "\xA0\xB0\xC0\xD0", "xyz\x80", /* unexpected continuation bytes */ "\x80xyz", "xyz\xBF", "\xBFxyz", "\xC0xyz", /* lonely start characters */ "x\xC0yz", "xy\xC0z", "xyz\xC0", "\xDFxyz", "x\xDFyz", "xy\xDFz", "xyz\xDF", "\xE0xyz", "x\xE0yz", "xy\xE0z", "xyz\xE0", "\xE0\xBFxy", "x\xE0\xBFy", "xy\xE0\xBF", "\xEFxyz", "x\xEFyz", "xy\xEFz", "xyz\xEF", "\xEF\x80xy", "x\xEF\x80y", "xy\xEF\x80", "\xF0xyz", "x\xF0yz", "xy\xF0z", "xyz\xF0", "\xF7xyz", "x\xF7yz", "xy\xF7z", "xyz\xF7", "\xF8xyz", "x\xF8yz", "xy\xF8z", "xyz\xF8", "\xFBxyz", "x\xFByz", "xy\xFBz", "xyz\xFB", "\xFCxyz", "x\xFCyz", "xy\xFCz", "xyz\xFC", "\xFDxyz", "x\xFDyz", "xy\xFDz", "xyz\xFD", "\xC0\xC0xy", /* last continuation byte missing */ "x\xC0\xC0y", "xy\xC0\xC0", "\xDF\xDFxy", "x\xDF\xDFy", "xy\xDF\xDF", "\xE0\x80xy", "x\xE0\x80y", "xy\xE0\x80", "\xEF\x80xy", "x\xEF\x80y", "xy\xEF\x80", "\xF0\x80\x80x", "x\xF0\x80\x80", "\xF7\x80\x80x", "x\xF7\x80\x80", "\xF8\x80\x80\x80x", "x\xF8\x80\x80\x80", "\xFB\x80\x80\x80x", "x\xFB\x80\x80\x80", "\xFC\x80\x80\x80\x80x", "x\xFC\x80\x80\x80\x80", "\xFD\x80\x80\x80\x80x", "x\xFD\x80\x80\x80\x80", "\xFExyz", /* impossible bytes */ "x\xFEyz", "xy\xFEz", "xyz\xFE", "\xFFxyz", "x\xFFyz", "xy\xFFz", "xyz\xFF", "\xC0\xAFxy", /* overlong sequences */ "x\xC0\xAFy", "xy\xC0\xAF", "\xE0\x80\xAFx", "x\xE0\x80\xAF", "\xF0\x80\x80\xAFx", "x\xF0\x80\x80\xAF", "\xF8\x80\x80\x80\xAFx", "x\xF8\x80\x80\x80\xAF", "\xFC\x80\x80\x80\x80\xAFx", "x\xFC\x80\x80\x80\x80\xAF", "\xC1\xBFxy", "x\xC1\xBFy", "xy\xC1\xBF", "\xE0\x9F\xBFx", "x\xE0\x9F\xBF", "\xF0\x8F\xBF\xBFx", "x\xF0\x8F\xBF\xBF", "\xF8\x87\xBF\xBF\xBFx", "x\xF8\x87\xBF\xBF\xBF", "\xFC\x83\xBF\xBF\xBF\xBFx", "x\xFC\x83\xBF\xBF\xBF\xBF", "x\xC0\x80", /* overlong NULs */ "x\xE0\x80\x80", "x\xF0\x80\x80\x80", "x\xF8\x80\x80\x80\x80", "x\xFC\x80\x80\x80\x80\x80", /* single UTF-16 surrogates */ "x\xED\xA0\x80", "x\xED\xAD\xBF", "x\xED\xAE\x80", "x\xED\xAF\xBF", "x\xED\xB0\x80", "x\xED\xBE\x80", "x\xED\xBF\xBF", "x\xED\xA0\x80\xED\xB0\x80", /* paired UTF-16 surrogates */ "x\xED\xA0\x80\xED\xBF\xBF", "x\xED\xAD\xBF\xED\xB0\x80", "x\xED\xAD\xBF\xED\xBF\xBF", "x\xED\xAE\x80\xED\xB0\x80", "x\xED\xAE\x80\xED\xBF\xBF", "x\xED\xAF\xBF\xED\xB0\x80", "x\xED\xAF\xBF\xED\xBF\xBF" #if 0 /* The two below is legal since UTF8PROC_VERSION_MAJOR 2 */ "x\xEF\xBF\xBE", /* other illegal code positions */ "x\xEF\xBF\xBF" #endif }; int nerrs=0; int i, j; #define NUM_BAD (sizeof notvalid / sizeof notvalid[0]) #define NUM_GOOD (sizeof valid / sizeof valid[0]) int ncid, dimid, varid, res; double attvals[] = {-2.0}; double attvals_in[1]; #define NATTVALS (sizeof attvals / sizeof attvals[0]) char *attstring = "text"; #define MAX_ATTSTRING_LEN 100 char attstr_in[MAX_ATTSTRING_LEN]; int dimids[NUM_GOOD]; int varids[NUM_GOOD]; #if 0 int attnums[NUM_GOOD]; #endif char *testfile = FILE_NAME; int formats[] = { NC_FORMAT_CLASSIC , NC_FORMAT_64BIT_OFFSET #ifdef ENABLE_CDF5 , NC_FORMAT_CDF5 #endif #ifdef USE_HDF5 , NC_FORMAT_NETCDF4 , NC_FORMAT_NETCDF4_CLASSIC #endif /* USE_HDF5 */ }; int num_formats = (sizeof formats) / (sizeof formats[0]); char *format_names[] = { "classic", "64-bit offset", "64-bit data", "netCDF-4/HDF5", "netCDF-4 classic model" }; printf("\n*** testing names with file %s...\n", testfile); for (j = 0; j < num_formats; j++) { printf("*** switching to netCDF %s format...", format_names[j]); nc_set_default_format(formats[j], NULL); if((res = nc_create(testfile, NC_CLOBBER, &ncid))) ERROR /* Define dimensions, variables, and attributes with various * acceptable names */ for (i = 0; i < NUM_GOOD; i++) { if ((res = nc_def_dim(ncid, valid[i], DIMLEN, &dimid))) ERRORI dimids[i] = dimid; /* Define variable with same name */ if ((res = nc_def_var(ncid, valid[i], NC_FLOAT, NDIMS, &dimids[i], &varid))) ERRORI varids[i] = varid; /* Define variable and global attributes with same name and value */ if ((res = nc_put_att_text(ncid, varid, valid[i], strlen(valid[i]), valid[i]))) ERRORI if ((res = nc_put_att_double(ncid, NC_GLOBAL, valid[i], NC_DOUBLE, NATTVALS, attvals))) ERRORI #if 0 attnums[i] = i; #endif } /* Try defining dimensions, variables, and attributes with various * bad names and make sure these are rejected */ for (i = 0; i < NUM_BAD; i++) { if ((res = nc_def_dim(ncid, notvalid[i], DIMLEN, &dimid)) != NC_EBADNAME) ERRORI if ((res = nc_def_var(ncid, notvalid[i], NC_FLOAT, NDIMS, dimids, &varid)) != NC_EBADNAME) ERRORI if ((res = nc_put_att_text(ncid, varid, notvalid[i], strlen(attstring), attstring)) != NC_EBADNAME) ERRORI if ((res = nc_put_att_double(ncid, NC_GLOBAL, notvalid[i], NC_DOUBLE, NATTVALS, attvals)) != NC_EBADNAME) ERRORI } if ((res = nc_enddef(ncid))) ERROR if ((res = nc_close(ncid))) ERROR /* Check it out, make sure all objects with good names were defined OK */ if ((res = nc_open(testfile, NC_NOWRITE, &ncid))) ERROR for (i = 0; i < NUM_GOOD; i++) { size_t attlen; if ((res = nc_inq_dimid(ncid, valid[i], &dimid)) || dimid != dimids[i]) ERRORI if ((res = nc_inq_varid(ncid, valid[i], &varid)) || varid != varids[i]) ERRORI res = nc_inq_attlen(ncid, varid, valid[i], &attlen); if ((res = nc_get_att_text(ncid, varid, valid[i], attstr_in))) ERRORI attstr_in[attlen] = '\0'; if (strcmp(valid[i], attstr_in) != 0) ERRORI if ((res = nc_get_att_double(ncid, NC_GLOBAL, valid[i], attvals_in)) || attvals[0] != attvals_in[0]) ERRORI } if ((res = nc_close(ncid))) ERROR /* (void) remove(testfile); */ SUMMARIZE_ERR; } total_err += nerrs; FINAL_RESULTS; return 0; }