From f8ec45d20d7f0df87db53c8391b86b7faa6ffa32 Mon Sep 17 00:00:00 2001 From: Russ Rew Date: Mon, 3 Dec 2012 21:15:30 +0000 Subject: [PATCH 1/4] Fix NCF-209, bug causing netcdf-fortran build to get assertion violation in 'make check' --- libsrc/nc3internal.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/libsrc/nc3internal.c b/libsrc/nc3internal.c index 922fb3997..0c85c645d 100644 --- a/libsrc/nc3internal.c +++ b/libsrc/nc3internal.c @@ -1097,7 +1097,7 @@ NC3_close(int ncid) status = NC_endef(nc3, 0, 1, 0, 1); /* TODO: defaults */ if(status != NC_NOERR ) { - (void) NC3_abort(ncid); /* do not use nc_abort */ + (void) nc_abort(ncid); return status; } } @@ -1541,24 +1541,12 @@ nc_delete_mp(const char * path, int basepe) if(basepe != 0) return NC_EINVAL; #endif - - assert(nc3->flags == 0); - - status = nc_get_NC(nc3); - if(status != NC_NOERR) - { - /* Not a netcdf file, don't delete */ - /* ??? is this the right semantic? what if it was just too big? */ - (void)NC3_abort(ncid); + + (void) nc_close(ncid); + if(unlink(path) == -1) { + return NC_EIO; /* No more specific error code is appropriate */ } - else - { - /* ncio_abort does the unlink */ - /*cheat and mark the file as new */ - fSet((nc3)->nciop->ioflags,NC_WRITE); - (void)NC3_abort(ncid); - } - return status; + return NC_NOERR; } int From 97344d8551b51321e546dfc7289135fbdc981e40 Mon Sep 17 00:00:00 2001 From: Dennis Heimbigner Date: Tue, 4 Dec 2012 03:32:41 +0000 Subject: [PATCH 2/4] make consistent with svn/oc2.0 --- oc2/Make0 | 3 ++- oc2/oc.c | 18 ++++++++++++++++++ oc2/oc.h | 16 +++++++++------- oc2/occurlfunctions.c | 6 ++++++ oc2/ocdump.c | 2 +- oc2/ochttp.c | 4 ---- oc2/ocinternal.c | 17 +++++++++++++++++ oc2/ocinternal.h | 5 +++++ oc2/ocrc.c | 13 +++++++++---- oc2/ocread.c | 5 +++-- oc2/ocutil.c | 3 +-- 11 files changed, 71 insertions(+), 21 deletions(-) diff --git a/oc2/Make0 b/oc2/Make0 index c00233281..0d82a1d2f 100755 --- a/oc2/Make0 +++ b/oc2/Make0 @@ -1,5 +1,6 @@ THISDIR=../oc2 -OCDIR=/home/dmh/svn/oc2.0 +#OCDIR=/home/dmh/svn/oc2.0 +OCDIR=f:/svn/oc2.0 # Make consistent with Makefile.am SRC=oc.c \ diff --git a/oc2/oc.c b/oc2/oc.c index bbad5fd30..69223ce5b 100644 --- a/oc2/oc.c +++ b/oc2/oc.c @@ -1655,6 +1655,24 @@ oc_ping(const char* url) return ocping(url); } +/*! +Set the user agent field. + +\param[in] agent The user agent string + +\retval OC_NOERR if the request succeeded. +\retval OC_EINVAL if the request failed, typically + because the agent string is null or zero-length. +*/ + +OCerror +oc_set_useragent(OCobject link, const char* agent) +{ + OCstate* state; + OCVERIFY(OC_State,link); + OCDEREF(OCstate*,state,link); + return ocsetuseragent(state,agent); +} /**@}*/ diff --git a/oc2/oc.h b/oc2/oc.h index 676901f06..7d3aac418 100644 --- a/oc2/oc.h +++ b/oc2/oc.h @@ -363,7 +363,6 @@ extern OCerror oc_data_readscalar(OClink, OCdatanode, size_t, void*); */ extern OCerror oc_data_readn(OClink, OCdatanode, size_t*, size_t, size_t, void*); - /* Return the indices for this datas; Assumes the data was obtained using oc_data_ithelement or oc_data_ithrecord; if not, then an error is returned. @@ -425,12 +424,12 @@ extern void oc_logtext(int tag, const char* text); /**************************************************/ /* Miscellaneous */ -/* For some reason, the MSVC compiler doesn't like this. */ -#ifndef _MSC_VER /* Return the size of the in-memory or on-disk data chunk returned by the server for a given tree. Zero implies it is not defined. */ +/* For some reason, the MSVC compiler doesn't like this. */ +#ifndef _MSC_VER extern OCerror oc_raw_xdrsize(OClink,OCddsnode,off_t*); #endif @@ -450,9 +449,6 @@ extern const char* oc_errstring(OCerror err); */ extern const char* oc_clientparam_get(OClink, const char* param); -/* Test is a given url responds to a DAP protocol request */ -extern OCerror oc_ping(const char* url); - /**************************************************/ /* Merging operations */ @@ -468,7 +464,7 @@ extern OCerror oc_svcerrordata(OClink link, char** codep, char** msgp, long* httpp); /**************************************************/ -/* Experimental */ +/* Experimental/Undocumented */ /* Resend a url as a head request to check the Last-Modified time */ extern OCerror oc_update_lastmodified_data(OClink); @@ -476,6 +472,12 @@ extern OCerror oc_update_lastmodified_data(OClink); /* Get last known modification time; -1 => data unknown */ extern long oc_get_lastmodified_data(OClink); +/* Test if a given url responds to a DAP protocol request */ +extern OCerror oc_ping(const char* url); + +/* Allow the setting of the user agent */ +extern OCerror oc_set_useragent(OClink, const char* agent); + #ifdef __cplusplus } #endif diff --git a/oc2/occurlfunctions.c b/oc2/occurlfunctions.c index c52edc8c2..2bb94826d 100644 --- a/oc2/occurlfunctions.c +++ b/oc2/occurlfunctions.c @@ -90,6 +90,12 @@ ocset_curl_flags(OCstate* state) OCDBG1(1,"CURLOPT_TIMEOUT=%ld",1L); } + if (flags->useragent) { + cstat = curl_easy_setopt(curl, CURLOPT_USERAGENT, flags->useragent); + if (cstat != CURLE_OK) goto done; + OCDBG1(1,"CURLOPT_USERAGENT=%s",flags->useragent); + } + /* Following are always set */ cstat = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); OCDBG1(1,"CURLOPT_FOLLOWLOCATION=%ld",1L); diff --git a/oc2/ocdump.c b/oc2/ocdump.c index a580164f5..426d21458 100644 --- a/oc2/ocdump.c +++ b/oc2/ocdump.c @@ -298,7 +298,7 @@ dumpfield(int index, char* n8, int isxdr) sprintf(stmp,"\\%02x",c); else sprintf(stmp,"%c",c); - strncat(tmp,stmp,4); + strncat(tmp,stmp,strlen(stmp)); } } diff --git a/oc2/ochttp.c b/oc2/ochttp.c index b02f78563..7119a2d42 100644 --- a/oc2/ochttp.c +++ b/oc2/ochttp.c @@ -238,10 +238,6 @@ occurlopen(CURL** curlp) cstat = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); if (cstat != CURLE_OK) stat = OC_ECURL; - /* some servers don't like requests that are made without a user-agent */ - cstat = curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); - if (cstat != CURLE_OK) - stat = OC_ECURL; } if (curlp) *curlp = curl; diff --git a/oc2/ocinternal.c b/oc2/ocinternal.c index 48838b5e1..9828ff568 100644 --- a/oc2/ocinternal.c +++ b/oc2/ocinternal.c @@ -552,6 +552,12 @@ ocsetcurlproperties(OCstate* state) state->creds.username = nulldup(state->uri->user); } } + if(state->curlflags.useragent == null) { + size_t len = strlen(DFALTUSERAGENT) + strlen(VERSION) + 1; + char* agent = (char*)malloc(len); + snprintf(agent,len+1,"%s%s",DFALTUSERAGENT,VERSION); + state->curlflags.useragent = agent; + } return; fail: @@ -559,3 +565,14 @@ fail: oclog(OCLOGERR, "curl error: %s", curl_easy_strerror(cstat)); return; } + +OCerror +ocsetuseragent(OCstate* state, const char* agent) +{ + if(state->curlflags.useragent != NULL) + free(state->curlflags.useragent); + state->curlflags.useragent = strdup(agent); + if(state->curlflags.useragent == NULL) + return OC_ENOMEM; + return OC_NOERR; +} diff --git a/oc2/ocinternal.h b/oc2/ocinternal.h index 48d60543d..991f83fcb 100644 --- a/oc2/ocinternal.h +++ b/oc2/ocinternal.h @@ -96,6 +96,9 @@ typedef struct OCheader { /* Default maximum memory packet size */ #define DFALTMAXPACKETSIZE 0x3000000 /*approximately 50M bytes*/ +/* Default user agent string (will have version appended)*/ +#define DFALTUSERAGENT "oc" + /* Collect global state info in one place */ extern struct OCGLOBALSTATE { int initialized; @@ -198,4 +201,6 @@ extern OCerror ocupdatelastmodifieddata(OCstate* state); extern int ocinternalinitialize(void); +extern OCerror ocsetuseragent(OCstate* state, const char* agent); + #endif /*COMMON_H*/ diff --git a/oc2/ocrc.c b/oc2/ocrc.c index 79075fc44..01282e2e1 100644 --- a/oc2/ocrc.c +++ b/oc2/ocrc.c @@ -329,7 +329,7 @@ ocdodsrc_read(char* basename, char* path) /* trim again */ line = rctrimleft(line,TRIMCHARS); /* save the url */ - strncpy(ocdodsrc->triples[ocdodsrc->ntriples].url,TRIM(url),2047); + strncpy(ocdodsrc->triples[ocdodsrc->ntriples].url,TRIM(url),strlen(url)); } if(strlen(line)==0) continue; /* empty line */ /* split off key and value */ @@ -346,8 +346,8 @@ ocdodsrc_read(char* basename, char* path) } *value = '\0'; value++; - strncpy(ocdodsrc->triples[ocdodsrc->ntriples].key,TRIM(key),2047); - strncpy(ocdodsrc->triples[ocdodsrc->ntriples].value,TRIM(value),2047); + strncpy(ocdodsrc->triples[ocdodsrc->ntriples].key,TRIM(key),strlen(key)); + strncpy(ocdodsrc->triples[ocdodsrc->ntriples].value,TRIM(value),strlen(value)); ocdodsrc->ntriples++; } fclose(in_file); @@ -355,7 +355,6 @@ ocdodsrc_read(char* basename, char* path) return 1; } - int ocdodsrc_process(OCstate* state) { @@ -381,6 +380,12 @@ ocdodsrc_process(OCstate* state) if(ocdebug > 0) oclog(OCLOGNOTE,"curl.timeout: %ld", state->curlflags.timeout); } + if((value = curllookup("USERAGENT",url)) != NULL) { + if(atoi(value)) state->curlflags.useragent = strdup(TRIM(value)); + if(!state->curlflags.useragent) {stat = OC_ENOMEM; goto done;} + if(ocdebug > 0) + oclog(OCLOGNOTE,"USERAGENT: %s", state->curlflags.useragent); + } if((value = curllookup("COOKIEFILE",url)) != NULL) { state->curlflags.cookiefile = strdup(TRIM(value)); diff --git a/oc2/ocread.c b/oc2/ocread.c index 5de29ce5e..1c235f505 100644 --- a/oc2/ocread.c +++ b/oc2/ocread.c @@ -14,7 +14,6 @@ #ifdef _MSC_VER #include #endif - #include "ocinternal.h" #include "ocdebug.h" #include "ochttp.h" @@ -212,7 +211,9 @@ readfile(const char* path, const char* suffix, OCbytes* packet) off_t totalread = 0; /* check for leading file:/// */ if(ocstrncmp(path,"file://",7)==0) path += 7; /* assume absolute path*/ - snprintf(filename,sizeof(filename),"%s%s",path,(suffix == NULL ? "" : suffix)); + snprintf(filename,sizeof(filename),"%s%s", + path, + (suffix != NULL ? suffix : "")); flags = O_RDONLY; #ifdef O_BINARY flags |= O_BINARY; diff --git a/oc2/ocutil.c b/oc2/ocutil.c index d24e73fe6..a78b61c2c 100644 --- a/oc2/ocutil.c +++ b/oc2/ocutil.c @@ -528,8 +528,7 @@ NULL, const char* ocdtmodestring(OCDT mode,int compact) { -#define MAXMODESTRING (NMODES*(MAXMODENAME+1)) - static char result[1+MAXMODESTRING]; /* hack to avoid malloc */ + static char result[1+(NMODES*(MAXMODENAME+1))]; /* hack to avoid malloc */ int i; char* p = result; result[0] = '\0'; From ec761ec8fb4664eaccef69ce19171af9a44ba355 Mon Sep 17 00:00:00 2001 From: Dennis Heimbigner Date: Tue, 4 Dec 2012 23:32:32 +0000 Subject: [PATCH 3/4] null=>NULL error --- oc2/ocinternal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oc2/ocinternal.c b/oc2/ocinternal.c index 9828ff568..2f0c08297 100644 --- a/oc2/ocinternal.c +++ b/oc2/ocinternal.c @@ -552,7 +552,7 @@ ocsetcurlproperties(OCstate* state) state->creds.username = nulldup(state->uri->user); } } - if(state->curlflags.useragent == null) { + if(state->curlflags.useragent == NULL) { size_t len = strlen(DFALTUSERAGENT) + strlen(VERSION) + 1; char* agent = (char*)malloc(len); snprintf(agent,len+1,"%s%s",DFALTUSERAGENT,VERSION); From f844126d0eb15e07df79ea9769c67651706dc232 Mon Sep 17 00:00:00 2001 From: Ward Fisher Date: Wed, 5 Dec 2012 17:44:39 +0000 Subject: [PATCH 4/4] Addressed a buffer overrun issue; making the assumption this is an error. On the off chance it wasn't an error, a proper fix will be formulated. --- oc2/ocinternal.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/oc2/ocinternal.c b/oc2/ocinternal.c index 2f0c08297..532ab6e65 100644 --- a/oc2/ocinternal.c +++ b/oc2/ocinternal.c @@ -324,7 +324,8 @@ createtempfile(OCstate* state, OCtree* tree) fd = createtempfile1(TMPPATH2,&name); if(fd < 0) { oclog(OCLOGERR,"oc_open: attempt to open tmp file failed: %s",name); - return errno; + if(name) free(name); + return errno; } #ifdef OCDEBUG oclog(OCLOGNOTE,"oc_open: using tmp file: %s",name); @@ -368,6 +369,9 @@ createtempfile1(char* tmppath, char** tmpnamep) #endif /* !HAVE_MKSTEMP */ if(tmpname == NULL) return -1; if(tmpnamep) *tmpnamep = tmpname; + else + free(tmpname); + return fd; } @@ -555,7 +559,7 @@ ocsetcurlproperties(OCstate* state) if(state->curlflags.useragent == NULL) { size_t len = strlen(DFALTUSERAGENT) + strlen(VERSION) + 1; char* agent = (char*)malloc(len); - snprintf(agent,len+1,"%s%s",DFALTUSERAGENT,VERSION); + snprintf(agent,len,"%s%s",DFALTUSERAGENT,VERSION); state->curlflags.useragent = agent; } return;