]> git.street.me.uk Git - andy/viking.git/commitdiff
Fix crash if a map configuration has no hostname or URL defined.
authorRob Norris <rw_norris@hotmail.com>
Sun, 7 Aug 2016 09:53:36 +0000 (10:53 +0100)
committerRob Norris <rw_norris@hotmail.com>
Mon, 8 Aug 2016 20:47:32 +0000 (21:47 +0100)
Generally improve handling of download hostname and uri parameters and report if not set.

src/curl_download.c
src/curl_download.h
src/download.c
src/download.h
src/vikdemlayer.c
src/vikmapslayer.c

index a439f9042d341b9ed3bbd9b2faf3cb7025b95115..40a1fbd7f85b09271df428cda506df37f5d74c4a 100644 (file)
@@ -96,7 +96,10 @@ void curl_download_uninit()
   curl_global_cleanup();
 }
 
-int curl_download_uri ( const char *uri, FILE *f, DownloadFileOptions *options, CurlDownloadOptions *cdo, void *handle )
+/**
+ *
+ */
+CURL_download_t curl_download_uri ( const char *uri, FILE *f, DownloadFileOptions *options, CurlDownloadOptions *cdo, void *handle )
 {
   CURL *curl;
   struct curl_slist *curl_send_headers = NULL;
@@ -183,25 +186,30 @@ int curl_download_uri ( const char *uri, FILE *f, DownloadFileOptions *options,
   return res;
 }
 
-int curl_download_get_url ( const char *hostname, const char *uri, FILE *f, DownloadFileOptions *options, gboolean ftp, CurlDownloadOptions *cdo, void *handle )
+/**
+ * curl_download_get_url:
+ *  Either hostname or uri should be defined
+ *
+ */
+CURL_download_t curl_download_get_url ( const char *hostname, const char *uri, FILE *f, DownloadFileOptions *options, gboolean ftp, CurlDownloadOptions *cdo, void *handle )
 {
-  int ret;
   gchar *full = NULL;
 
-  if ( strstr ( hostname, "://" ) != NULL )
+  if ( hostname && strstr ( hostname, "://" ) != NULL )
     /* Already full url */
     full = (gchar *) hostname;
-  else if ( strstr ( uri, "://" ) != NULL )
+  else if ( uri && strstr ( uri, "://" ) != NULL )
     /* Already full url */
     full = (gchar *) uri;
-  else
+  else if ( hostname && uri )
     /* Compose the full url */
     full = g_strdup_printf ( "%s://%s%s", (ftp?"ftp":"http"), hostname, uri );
-  ret = curl_download_uri ( full, f, options, cdo, handle );
-  /* Free newly allocated memory, but do not free uri */
-  if ( hostname != full && uri != full )
-    g_free ( full );
-  full = NULL;
+  else {
+    return CURL_DOWNLOAD_ERROR;
+  }
+
+  CURL_download_t ret = curl_download_uri ( full, f, options, cdo, handle );
+  g_free ( full );
 
   return ret;
 }
index 8f266530207244ead54461f1dac8c257e21b6488..0696f13bc013f2cb4f8c3773a0aa10a1ac3ed4aa 100644 (file)
 G_BEGIN_DECLS
 
 /* Error messages returned by download functions */
-enum { CURL_DOWNLOAD_NO_ERROR = 0,
-       CURL_DOWNLOAD_NO_NEWER_FILE,
-       CURL_DOWNLOAD_ERROR };
+typedef enum {
+  CURL_DOWNLOAD_NO_ERROR = 0,
+  CURL_DOWNLOAD_NO_NEWER_FILE,
+  CURL_DOWNLOAD_ERROR
+} CURL_download_t;
 
 typedef struct {
   /**
@@ -51,8 +53,8 @@ typedef struct {
 
 void curl_download_init ();
 void curl_download_uninit ();
-int curl_download_get_url ( const char *hostname, const char *uri, FILE *f, DownloadFileOptions *options, gboolean ftp, CurlDownloadOptions *curl_options, void *handle );
-int curl_download_uri ( const char *uri, FILE *f, DownloadFileOptions *options, CurlDownloadOptions *curl_options, void *handle );
+CURL_download_t curl_download_get_url ( const char *hostname, const char *uri, FILE *f, DownloadFileOptions *options, gboolean ftp, CurlDownloadOptions *curl_options, void *handle );
+CURL_download_t curl_download_uri ( const char *uri, FILE *f, DownloadFileOptions *options, CurlDownloadOptions *curl_options, void *handle );
 void * curl_download_handle_init ();
 void curl_download_handle_cleanup ( void * handle );
 
index 7eab8c7787dd638c0318596e4a24f2279bf47916..d8cde072c347630a8bf1e8d773ecb9555c7d40c0 100644 (file)
@@ -319,7 +319,6 @@ static void set_etag(const char *fn, const char *fntmp, CurlDownloadOptions *cdo
 static DownloadResult_t download( const char *hostname, const char *uri, const char *fn, DownloadFileOptions *options, gboolean ftp, void *handle)
 {
   FILE *f;
-  int ret;
   gchar *tmpfilename;
   gboolean failure = FALSE;
   CurlDownloadOptions cdo = {0, NULL, NULL};
@@ -357,6 +356,12 @@ static DownloadResult_t download( const char *hostname, const char *uri, const c
     g_free ( dir );
   }
 
+  // Early test for valid hostname & uri to avoid unnecessary tmp file
+  if ( !hostname && !uri ) {
+    g_warning ( "%s: Parameter error - neither hostname nor uri defined", __FUNCTION__ );
+    return DOWNLOAD_PARAMETERS_ERROR;
+  }
+
   tmpfilename = g_strdup_printf("%s.tmp", fn);
   if (!lock_file ( tmpfilename ) )
   {
@@ -376,7 +381,7 @@ static DownloadResult_t download( const char *hostname, const char *uri, const c
   }
 
   /* Call the backend function */
-  ret = curl_download_get_url ( hostname, uri, f, options, ftp, &cdo, handle );
+  CURL_download_t ret = curl_download_get_url ( hostname, uri, f, options, ftp, &cdo, handle );
 
   DownloadResult_t result = DOWNLOAD_SUCCESS;
 
index 03a01006a72eb52ad17f1564b2487021affedab7..e2339e279cf2b892243669c790a32d6981d60405 100644 (file)
@@ -82,6 +82,7 @@ void a_download_init(void);
 void a_download_uninit(void);
 
 typedef enum {
+  DOWNLOAD_PARAMETERS_ERROR = -8, // Configuration issue
   DOWNLOAD_FILE_WRITE_ERROR = -4, // Can't write downloaded file :(
   DOWNLOAD_HTTP_ERROR = -2,
   DOWNLOAD_CONTENT_ERROR = -1,
index d229ad15bcde889e6dd9610d65e470b6102ee266..6d681a15ea29fa1bf0ed389dfdc5257ba5ff6e54 100644 (file)
@@ -960,6 +960,7 @@ static void srtm_dem_download_thread ( DEMDownloadParams *p, gpointer threaddata
   static DownloadFileOptions options = { FALSE, FALSE, NULL, 0, a_check_map_file, NULL, NULL };
   DownloadResult_t result = a_http_download_get_url ( SRTM_HTTP_SITE, src_fn, p->dest, &options, NULL );
   switch ( result ) {
+    case DOWNLOAD_PARAMETERS_ERROR:
     case DOWNLOAD_CONTENT_ERROR:
     case DOWNLOAD_HTTP_ERROR: {
       gchar *msg = g_strdup_printf ( _("DEM download failure for %f, %f"), p->lat, p->lon );
index 7514385cbd8225bb83caecb3ec42ca6ad26ef49f..6bb17a4af1a9b022973e92959d9d3b922a30d5e2 100644 (file)
@@ -1636,6 +1636,7 @@ static int map_download_thread ( MapDownloadInfo *mdi, gpointer threaddata )
         if (need_download) {
           DownloadResult_t dr = vik_map_source_download( MAPS_LAYER_NTH_TYPE(mdi->maptype), &(mdi->mapcoord), mdi->filename_buf, handle);
           switch ( dr ) {
+            case DOWNLOAD_PARAMETERS_ERROR:
             case DOWNLOAD_HTTP_ERROR:
             case DOWNLOAD_CONTENT_ERROR: {
               // TODO: ?? count up the number of download errors somehow...