@@ -20,7 +20,9 @@ extern "C" {
2020#include <errno.h>
2121#include <memory.h>
2222#include <stdint.h>
23+ #include <stdio.h>
2324#include <stdlib.h>
25+ #include <string.h>
2426
2527#include <acquire_common_defs.h>
2628#include <acquire_fileutils.h>
@@ -67,7 +69,7 @@ static int get_oname_from_cd(char const *const cd, char *oname) {
6769 /* If filename is present */
6870 val = strcasestr ((const char * )cd , (const char * )key );
6971 if (!val ) {
70- fprintf (stderr , "No key-value for \"%s\" in \"%s\"" , key , cdtag );
72+ fprintf (stderr , "No key-value for \"%s\" in \"%s\"\n " , key , cdtag );
7173 return EXIT_FAILURE ;
7274 }
7375
@@ -94,8 +96,12 @@ static int get_oname_from_url(char const *url, char *oname) {
9496
9597 u = strrchr (u , '/' );
9698
99+ if (!u )
100+ u = url ; /* fallback if no '/' */
101+
97102 /* Remove last '/' */
98- u ++ ;
103+ else
104+ u ++ ;
99105
100106 /* Copy value as oname */
101107 while (* u != '\0' ) {
@@ -109,9 +115,9 @@ static int get_oname_from_url(char const *url, char *oname) {
109115
110116size_t dnld_header_parse (void * hdr , size_t size , size_t nmemb , void * userdata ) {
111117 const size_t cb = size * nmemb ;
112- const char * hdr_str = hdr ;
118+ const char * hdr_str = ( const char * ) hdr ;
113119 struct dnld_params_t * dnld_params = (struct dnld_params_t * )userdata ;
114- char const * const cdtag = "Content-disposition:" ;
120+ const char * const cdtag = "Content-disposition:" ;
115121
116122 /* Example:
117123 * ...
@@ -126,16 +132,18 @@ size_t dnld_header_parse(void *hdr, size_t size, size_t nmemb, void *userdata) {
126132 int ret = get_oname_from_cd (hdr_str + strlen (cdtag ),
127133 dnld_params -> dnld_remote_fname );
128134 if (ret )
129- fprintf (stderr , "ERR: bad remote name" );
135+ fprintf (stderr , "ERR: bad remote name\n " );
130136 }
131137
132138 return cb ;
133139}
134140
135- FILE * get_dnld_stream (char const * const fname ) {
136- FILE * fp ;
137- #if defined(_MSC_VER ) || defined(__STDC_LIB_EXT1__ ) && __STDC_WANT_LIB_EXT1__
138- fopen_s (& fp , fname , "wb" );
141+ static FILE * get_dnld_stream (const char * const fname ) {
142+ FILE * fp = NULL ;
143+ #if defined(_MSC_VER ) || (defined(__STDC_LIB_EXT1__ ) && __STDC_WANT_LIB_EXT1__ )
144+ /* Use fopen_s if available */
145+ if (fopen_s (& fp , fname , "wb" ) != 0 )
146+ fp = NULL ;
139147#else
140148 fp = fopen (fname , "wb" );
141149#endif
@@ -147,9 +155,8 @@ FILE *get_dnld_stream(char const *const fname) {
147155 return fp ;
148156}
149157
150- size_t write_cb (const void * buffer , const size_t sz , size_t nmemb ,
151- void * userdata ) {
152- struct dnld_params_t * dnld_params = userdata ;
158+ size_t write_cb (const void * buffer , size_t sz , size_t nmemb , void * userdata ) {
159+ struct dnld_params_t * dnld_params = (struct dnld_params_t * )userdata ;
153160
154161 if (!dnld_params -> dnld_remote_fname [0 ]) {
155162 get_oname_from_url (dnld_params -> dnld_url , dnld_params -> dnld_remote_fname );
@@ -163,11 +170,11 @@ size_t write_cb(const void *buffer, const size_t sz, size_t nmemb,
163170 }
164171
165172 {
166- const size_t bytes_written =
173+ size_t elements_written =
167174 fwrite (buffer , sz , nmemb , dnld_params -> dnld_stream );
168- if (bytes_written == sz * nmemb ) {
169- dnld_params -> dnld_file_sz += bytes_written ;
170- return bytes_written ;
175+ if (elements_written == nmemb ) {
176+ dnld_params -> dnld_file_sz += sz * elements_written ;
177+ return sz * elements_written ;
171178 }
172179 }
173180
@@ -176,8 +183,8 @@ size_t write_cb(const void *buffer, const size_t sz, size_t nmemb,
176183
177184#if defined(LIBACQUIRE_IMPLEMENTATION ) && defined(DOWNLOAD_IMPL )
178185int download (const char * url , enum Checksum checksum , const char * hash ,
179- const char target_location [NAME_MAX ], bool follow , size_t retry ,
180- size_t verbosity ) {
186+ const char * target_location /* [NAME_MAX]*/ , bool follow ,
187+ size_t retry , size_t verbosity ) {
181188 CURL * curl ;
182189 CURLcode cerr = CURLE_OK ;
183190 struct dnld_params_t dnld_params ;
@@ -190,36 +197,51 @@ int download(const char *url, enum Checksum checksum, const char *hash,
190197 return EEXIST ;
191198 } else {
192199 /* treat target_location as a filename */
193- strncpy (dnld_params .dnld_remote_fname , target_location ,
194- sizeof (dnld_params .dnld_remote_fname ) - 1 );
195- dnld_params .dnld_remote_fname [sizeof (dnld_params .dnld_remote_fname ) - 1 ] =
196- '\0' ;
197- strncpy (dnld_params .dnld_full_local_fname , target_location ,
198- sizeof (dnld_params .dnld_full_local_fname ) - 1 );
199- dnld_params
200- .dnld_full_local_fname [sizeof (dnld_params .dnld_full_local_fname ) -
201- 1 ] = '\0' ;
200+ {
201+ size_t len = strlen (target_location );
202+ if (len >= sizeof (dnld_params .dnld_remote_fname ))
203+ len = sizeof (dnld_params .dnld_remote_fname ) - 1 ;
204+ memcpy (dnld_params .dnld_remote_fname , target_location , len );
205+ dnld_params .dnld_remote_fname [len ] = '\0' ;
206+ }
207+ {
208+ size_t len = strlen (target_location );
209+ if (len >= sizeof (dnld_params .dnld_full_local_fname ))
210+ len = sizeof (dnld_params .dnld_full_local_fname ) - 1 ;
211+ memcpy (dnld_params .dnld_full_local_fname , target_location , len );
212+ dnld_params .dnld_full_local_fname [len ] = '\0' ;
213+ }
202214 }
203215 } else if (is_relative (target_location )) {
204216 /* same as above */
205- strncpy (dnld_params .dnld_remote_fname , target_location ,
206- sizeof (dnld_params .dnld_remote_fname ) - 1 );
207- dnld_params .dnld_remote_fname [sizeof (dnld_params .dnld_remote_fname ) - 1 ] =
208- '\0' ;
209- strncpy (dnld_params .dnld_full_local_fname , target_location ,
210- sizeof (dnld_params .dnld_full_local_fname ) - 1 );
211- dnld_params
212- .dnld_full_local_fname [sizeof (dnld_params .dnld_full_local_fname ) - 1 ] =
213- '\0' ;
217+ {
218+ size_t len = strlen (target_location );
219+ if (len >= sizeof (dnld_params .dnld_remote_fname ))
220+ len = sizeof (dnld_params .dnld_remote_fname ) - 1 ;
221+ memcpy (dnld_params .dnld_remote_fname , target_location , len );
222+ dnld_params .dnld_remote_fname [len ] = '\0' ;
223+ }
224+ {
225+ size_t len = strlen (target_location );
226+ if (len >= sizeof (dnld_params .dnld_full_local_fname ))
227+ len = sizeof (dnld_params .dnld_full_local_fname ) - 1 ;
228+ memcpy (dnld_params .dnld_full_local_fname , target_location , len );
229+ dnld_params .dnld_full_local_fname [len ] = '\0' ;
230+ }
214231 } else if (!is_directory (target_location )) {
215232 fprintf (stderr ,
216233 "Create \"%s\" and ensure it's accessible, then try again\n" ,
217234 target_location );
218235 return CURLINFO_OS_ERRNO + 2 ;
219236 }
220237
221- strncpy (dnld_params .dnld_url , url , sizeof (dnld_params .dnld_url ) - 1 );
222- dnld_params .dnld_url [sizeof (dnld_params .dnld_url ) - 1 ] = '\0' ;
238+ {
239+ size_t len = strlen (url );
240+ if (len >= sizeof (dnld_params .dnld_url ))
241+ len = sizeof (dnld_params .dnld_url ) - 1 ;
242+ memcpy (dnld_params .dnld_url , url , len );
243+ dnld_params .dnld_url [len ] = '\0' ;
244+ }
223245
224246 curl_global_init (CURL_GLOBAL_ALL );
225247
@@ -265,11 +287,13 @@ int download(const char *url, enum Checksum checksum, const char *hash,
265287 path = get_path_from_url (url );
266288 if (strlen (path ) >= sizeof (dnld_params .dnld_remote_fname ))
267289 path = "" ; /* fail silently, will error below */
268-
269- strncpy (dnld_params .dnld_remote_fname , path ,
270- sizeof (dnld_params .dnld_remote_fname ) - 1 );
271- dnld_params .dnld_remote_fname [sizeof (dnld_params .dnld_remote_fname ) - 1 ] =
272- '\0' ;
290+ {
291+ size_t len = strlen (path );
292+ if (len >= sizeof (dnld_params .dnld_remote_fname ))
293+ len = sizeof (dnld_params .dnld_remote_fname ) - 1 ;
294+ memcpy (dnld_params .dnld_remote_fname , path , len );
295+ dnld_params .dnld_remote_fname [len ] = '\0' ;
296+ }
273297 }
274298
275299 if (dnld_params .dnld_full_local_fname [0 ] == '\0' ) {
0 commit comments