>From 448e3c06cd9589509cd3914a43fe4c7e93e9d622 Mon Sep 17 00:00:00 2001 From: Matthew White Date: Mon, 22 Aug 2016 09:13:52 +0200 Subject: [PATCH 13/25] New: Metalink file size mismatch returns error code METALINK_SIZE_ERROR * src/wget.h (uerr_t): Add error code METALINK_SIZE_ERROR to enum * src/metalink.c (retrieve_from_metalink): Use boolean variable size_ok, when false set retr_err to METALINK_SIZE_ERROR * testenv/Makefile.am: Add new file * testenv/Test-metalink-xml-size.py: New file. Metalink/XML file size tests () Before this patch, no appropriate error code was returned to inform a file size mismatch. This patch introduces the error code METALINK_SIZE_ERROR to inform a file size mismatch. --- src/metalink.c | 11 +++ src/wget.h | 3 +- testenv/Makefile.am | 3 +- testenv/Test-metalink-xml-size.py | 203 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 218 insertions(+), 2 deletions(-) create mode 100755 testenv/Test-metalink-xml-size.py diff --git a/src/metalink.c b/src/metalink.c index 356a68b..9967705 100644 --- a/src/metalink.c +++ b/src/metalink.c @@ -101,6 +101,7 @@ retrieve_from_metalink (const metalink_t* metalink) char *basename = NULL; char *safename = NULL; char *destname = NULL; + bool size_ok = false; bool hash_ok = false; uerr_t retr_err = METALINK_MISSING_RESOURCE; @@ -327,10 +328,12 @@ retrieve_from_metalink (const metalink_t* metalink) continue; } + size_ok = false; logprintf (LOG_VERBOSE, _("Computing size for %s\n"), quote (destname)); if (!mfile->size) { + size_ok = true; logprintf (LOG_VERBOSE, _("File size not declared. Skipping check.\n")); } else @@ -358,6 +361,7 @@ retrieve_from_metalink (const metalink_t* metalink) } else { + size_ok = true; logputs (LOG_VERBOSE, _("Size matches.\n")); } } @@ -681,6 +685,13 @@ gpg_skip_verification: logprintf (LOG_VERBOSE, _("Failed to download %s. Skipping resource.\n"), quote (destname ? destname : safename)); } + else if (!size_ok) + { + retr_err = METALINK_SIZE_ERROR; + logprintf (LOG_NOTQUIET, + _("File %s retrieved but size does not match. " + "\n"), quote (destname)); + } else if (!hash_ok) { retr_err = METALINK_CHKSUM_ERROR; diff --git a/src/wget.h b/src/wget.h index eacf725..ed57245 100644 --- a/src/wget.h +++ b/src/wget.h @@ -361,7 +361,8 @@ typedef enum TIMECONV_ERR, METALINK_PARSE_ERROR, METALINK_RETR_ERROR, METALINK_CHKSUM_ERROR, METALINK_SIG_ERROR, METALINK_MISSING_RESOURCE, - RETR_WITH_METALINK + RETR_WITH_METALINK, + METALINK_SIZE_ERROR } uerr_t; /* 2005-02-19 SMS. diff --git a/testenv/Makefile.am b/testenv/Makefile.am index d117e50..5a67822 100644 --- a/testenv/Makefile.am +++ b/testenv/Makefile.am @@ -44,7 +44,8 @@ if METALINK_IS_ENABLED Test-metalink-xml-relprefix-trust.py \ Test-metalink-xml-absprefix-trust.py \ Test-metalink-xml-homeprefix-trust.py \ - Test-metalink-xml-continue.py + Test-metalink-xml-continue.py \ + Test-metalink-xml-size.py else METALINK_TESTS = endif diff --git a/testenv/Test-metalink-xml-size.py b/testenv/Test-metalink-xml-size.py new file mode 100755 index 0000000..5d776c4 --- /dev/null +++ b/testenv/Test-metalink-xml-size.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python3 +from sys import exit +from test.http_test import HTTPTest +from misc.wget_file import WgetFile +import re +import hashlib + +""" + This is to test Metalink/XML file size check in Wget. + + With --trust-server-names, trust the metalink:file names. + + Without --trust-server-names, don't trust the metalink:file names: + use the basename of --input-metalink, and add a sequential number + (e.g. .#1, .#2, etc.). + + Strip the directory from unsafe paths. +""" +############# File Definitions ############################################### +bad = "Ouch!" + +File1 = "Would you like some Tea?" +File1_lowPref = "Do not take this" +File1_sha256 = hashlib.sha256 (File1.encode ('UTF-8')).hexdigest () + +File2 = "This is gonna be good" +File2_lowPref = "Not this one too" +File2_sha256 = hashlib.sha256 (File2.encode ('UTF-8')).hexdigest () + +File3 = "A little more, please" +File3_lowPref = "That's just too much" +File3_sha256 = hashlib.sha256 (File3.encode ('UTF-8')).hexdigest () + +File4 = "Maybe a biscuit?" +File4_lowPref = "No, thanks" +File4_sha256 = hashlib.sha256 (File4.encode ('UTF-8')).hexdigest () + +File5 = "More Tea...?" +File5_lowPref = "I have to go..." +File5_sha256 = hashlib.sha256 (File5.encode ('UTF-8')).hexdigest () +File5_size = str (len (File5)) + +MetaXml = \ +""" + + + GNU Wget + + + GNU GPL + http://www.gnu.org/licenses/gpl.html + + Wget Test Files + 1.2.3 + Wget Test Files description + + + + + {{FILE1_HASH}} + + + http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file + http://{{SRV_HOST}}:{{SRV_PORT}}/404 + http://{{SRV_HOST}}:{{SRV_PORT}}/File1_lowPref + http://{{SRV_HOST}}:{{SRV_PORT}}/File1 + + + + 2 + + {{FILE2_HASH}} + + + http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file + http://{{SRV_HOST}}:{{SRV_PORT}}/404 + http://{{SRV_HOST}}:{{SRV_PORT}}/File2_lowPref + http://{{SRV_HOST}}:{{SRV_PORT}}/File2 + + + + 0 + + {{FILE3_HASH}} + + + http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file + http://{{SRV_HOST}}:{{SRV_PORT}}/404 + http://{{SRV_HOST}}:{{SRV_PORT}}/File3_lowPref + http://{{SRV_HOST}}:{{SRV_PORT}}/File3 + + + + -240 + + {{FILE4_HASH}} + + + http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file + http://{{SRV_HOST}}:{{SRV_PORT}}/404 + http://{{SRV_HOST}}:{{SRV_PORT}}/File4_lowPref + http://{{SRV_HOST}}:{{SRV_PORT}}/File4 + + + + {{FILE5_SIZE}} + + {{FILE5_HASH}} + + + http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file + http://{{SRV_HOST}}:{{SRV_PORT}}/404 + http://{{SRV_HOST}}:{{SRV_PORT}}/File5_lowPref + http://{{SRV_HOST}}:{{SRV_PORT}}/File5 + + + + +""" + +wrong_file = WgetFile ("wrong_file", bad) + +File1_orig = WgetFile ("File1", File1) +File1_down = WgetFile ("test.meta4.#1", File1) +File1_nono = WgetFile ("File1_lowPref", File1_lowPref) + +# wrong size +File2_orig = WgetFile ("File2", File2) +File2_nono = WgetFile ("File2_lowPref", File2_lowPref) + +File3_orig = WgetFile ("File3", File3) +File3_down = WgetFile ("test.meta4.#3", File3) +File3_nono = WgetFile ("File3_lowPref", File3_lowPref) + +File4_orig = WgetFile ("File4", File4) +File4_down = WgetFile ("test.meta4.#4", File4) +File4_nono = WgetFile ("File4_lowPref", File4_lowPref) + +File5_orig = WgetFile ("File5", File5) +File5_down = WgetFile ("test.meta4.#5", File5) +File5_nono = WgetFile ("File5_lowPref", File5_lowPref) + +MetaFile = WgetFile ("test.meta4", MetaXml) + +WGET_OPTIONS = "--input-metalink test.meta4" +WGET_URLS = [[]] + +Files = [[ + wrong_file, + File1_orig, File1_nono, + File2_orig, File2_nono, + File3_orig, File3_nono, + File4_orig, File4_nono, + File5_orig, File5_nono +]] +Existing_Files = [MetaFile] + +ExpectedReturnCode = 1 +ExpectedDownloadedFiles = [ + File1_down, + File3_down, + File4_down, + File5_down, + MetaFile +] + +################ Pre and Post Test Hooks ##################################### +pre_test = { + "ServerFiles" : Files, + "LocalFiles" : Existing_Files +} +test_options = { + "WgetCommands" : WGET_OPTIONS, + "Urls" : WGET_URLS +} +post_test = { + "ExpectedFiles" : ExpectedDownloadedFiles, + "ExpectedRetcode" : ExpectedReturnCode +} + +http_test = HTTPTest ( + pre_hook=pre_test, + test_params=test_options, + post_hook=post_test, +) + +http_test.server_setup() +### Get and use dynamic server sockname +srv_host, srv_port = http_test.servers[0].server_inst.socket.getsockname () + +MetaXml = re.sub (r'{{FILE1_HASH}}', File1_sha256, MetaXml) +MetaXml = re.sub (r'{{FILE2_HASH}}', File2_sha256, MetaXml) +MetaXml = re.sub (r'{{FILE3_HASH}}', File3_sha256, MetaXml) +MetaXml = re.sub (r'{{FILE4_HASH}}', File4_sha256, MetaXml) +MetaXml = re.sub (r'{{FILE5_HASH}}', File5_sha256, MetaXml) +MetaXml = re.sub (r'{{FILE5_SIZE}}', File5_size, MetaXml) +MetaXml = re.sub (r'{{SRV_HOST}}', srv_host, MetaXml) +MetaXml = re.sub (r'{{SRV_PORT}}', str (srv_port), MetaXml) +MetaFile.content = MetaXml + +err = http_test.begin () + +exit (err) -- 2.7.3