From 9cdc6f2a8584347fd6f6633df6dc11c2d406a877 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 7 Aug 2020 09:47:10 +0100 Subject: [PATCH] depends: Use FALLBACK_DOWNLOAD_PATH if the primary's hash doesn't match The previous behaviour was to use FALLBACK_DOWNLOAD_PATH to download dependencies if the primary did not resolve. This was not resilient against primaries that either mis-report HTTP status codes (e.g. SourceForge returning 200 OK alongside a 404 webpage), or did not guarantee artifacts to be bit-stable (e.g. GitHub regenerating commit archive caches in a non-reproducible manner); in either case, the incorrect file would be fetched and then the build would fail due to hash mismatch. The new behaviour is to download dependencies and check their hashes as an atomic operation, and use FALLBACK_DOWNLOAD_PATH if any part of the operation fails. --- depends/funcs.mk | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index f375c4131..c224eda54 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -19,13 +19,15 @@ define int_get_all_dependencies $(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dependencies)))) endef +define download_and_check_file +($(build_DOWNLOAD) "$(1)/$(2).temp" $(3) && echo "$(4) $(1)/$(2).temp" > $(1)/.$(2).hash && $(build_SHA256SUM) -c $(1)/.$(2).hash) +endef + define fetch_file (test -f $$($(1)_source_dir)/$(4) || \ ( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \ - ( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" || \ - $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(4)" ) && \ - echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \ - $(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \ + ( $(call download_and_check_file,$$($(1)_download_dir),$(4),"$(2)/$(3)",$(5)) || \ + $(call download_and_check_file,$$($(1)_download_dir),$(4),"$(FALLBACK_DOWNLOAD_PATH)/$(4)",$(5)) ) && \ mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \ rm -rf $$($(1)_download_dir) )) endef