[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
02/02: daemon: Read substitute nar size as 'unsigned long long'.
From: |
guix-commits |
Subject: |
02/02: daemon: Read substitute nar size as 'unsigned long long'. |
Date: |
Wed, 24 Nov 2021 18:20:01 -0500 (EST) |
civodul pushed a commit to branch master
in repository guix.
commit f9b1bb916c284bea00dd5549a43e0894b219d650
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Thu Nov 25 00:01:12 2021 +0100
daemon: Read substitute nar size as 'unsigned long long'.
Fixes <https://issues.guix.gnu.org/46212>.
Reported by Christopher Baines <mail@cbaines.net>.
Previously, the nar size returned by 'guix substitute' would be read as
an 'int'; thus, values above 2^31 - 1 would be read and then stored as
negative integers in the database.
Regression introduced in 9dfa20a22ae0be3d3b01a7b3d422af97428c627e.
* nix/libstore/build.cc (SubstitutionGoal::finished): Use templatized
'string2Int' instead of 'std::atoi' to get an 'unsigned long long',
which is the type of 'hash.second'.
* tests/store.scm ("substitute and large size"): New test.
---
nix/libstore/build.cc | 3 ++-
tests/store.scm | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index 5697ae5..f6431bb 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -3102,7 +3102,8 @@ void SubstitutionGoal::finished()
throw Error(format("unknown hash algorithm in `%1%'") %
hashStr);
case htSHA256:
hash.first = parseHash16or32(hashType, string(hashStr, n + 1));
- hash.second = std::atoi(statusList[2].c_str());
+ if (!string2Int(statusList[2], hash.second))
+ throw Error(format("invalid nar size for '%1%' substitute")
% storePath);
break;
default:
/* The database only stores SHA256 hashes, so compute it. */
diff --git a/tests/store.scm b/tests/store.scm
index 11ca440..de12f68 100644
--- a/tests/store.scm
+++ b/tests/store.scm
@@ -976,6 +976,50 @@ System: x86_64-linux~%"
(and (equal? (substitutable-path s) item)
(substitutable-nar-size s)))))))
+(test-equal "substitute and large size"
+ (+ 100 (expt 2 31)) ;<https://issues.guix.gnu.org/46212>
+ (with-store s
+ (let* ((size (+ 100 (expt 2 31))) ;does not fit in signed 'int'
+ (item (string-append (%store-prefix)
+ "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bad-size-"
+ (random-text)))
+ (nar (string-append (%substitute-directory) "/nar")))
+ ;; Create a dummy nar to allow for substitution.
+ (call-with-output-file nar
+ (lambda (port)
+ (write-file-tree (store-path-package-name item) port
+ #:file-type+size (lambda _
+ (values 'regular 12))
+ #:file-port (lambda _
+ (open-input-string "Hello world.")))))
+
+ ;; Create fake substituter data, to be read by 'guix substitute'.
+ (call-with-output-file (string-append (%substitute-directory)
+ "/" (store-path-hash-part item)
+ ".narinfo")
+ (lambda (port)
+ (format port "StorePath: ~a
+URL: file://~a
+Compression: none
+NarSize: ~a
+NarHash: sha256:~a
+References:
+System: x86_64-linux~%"
+ item nar size
+ (bytevector->nix-base32-string (gcrypt:file-sha256 nar)))))
+
+ ;; Remove entry from the local cache.
+ (false-if-exception
+ (delete-file-recursively (string-append (getenv "XDG_CACHE_HOME")
+ "/guix/substitute")))
+
+ ;; Make sure 'guix substitute' correctly communicates the above
+ ;; data.
+ (set-build-options s #:use-substitutes? #t
+ #:substitute-urls (%test-substitute-urls))
+ (ensure-path s item)
+ (path-info-nar-size (query-path-info s item)))))
+
(test-assert "export/import several paths"
(let* ((texts (unfold (cut >= <> 10)
(lambda _ (random-text))