From 9891e428eae0ed24e0d61862b3f5e298606b79eb Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Sun, 14 Jan 2018 20:31:33 -0500 Subject: [PATCH] utils: Prevent substitute from crashing on files containing NUL chars. Fixes issue #30116. * guix/build/utils.scm (substitute): Add condition to skip lines containing the NUL character. --- guix/build/utils.scm | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/guix/build/utils.scm b/guix/build/utils.scm index 7391307c8..975f4e70a 100644 --- a/guix/build/utils.scm +++ b/guix/build/utils.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2013 Andreas Enge ;;; Copyright © 2013 Nikita Karetnikov ;;; Copyright © 2015 Mark H Weaver +;;; Copyright © 2018 Maxim Cournoyer ;;; ;;; This file is part of GNU Guix. ;;; @@ -621,28 +622,35 @@ PROC as (PROC LINE MATCHES); PROC must return the line that will be written as a substitution of the original line. Be careful about using '$' to match the end of a line; by itself it won't match the terminating newline of a line." (let ((rx+proc (map (match-lambda - (((? regexp? pattern) . proc) - (cons pattern proc)) - ((pattern . proc) - (cons (make-regexp pattern regexp/extended) - proc))) + (((? regexp? pattern) . proc) + (cons pattern proc)) + ((pattern . proc) + (cons (make-regexp pattern regexp/extended) + proc))) pattern+procs))) (with-atomic-file-replacement file (lambda (in out) (let loop ((line (read-line in 'concat))) - (if (eof-object? line) - #t - (let ((line (fold (lambda (r+p line) - (match r+p - ((regexp . proc) - (match (list-matches regexp line) - ((and m+ (_ _ ...)) - (proc line m+)) - (_ line))))) - line - rx+proc))) - (display line out) - (loop (read-line in 'concat))))))))) + (cond + ((eof-object? line) + #t) + ((string-contains line (make-string 1 #\nul)) + ;; The regexp functions of the GNU C library (which Guile uses) + ;; cannot deal with NUL characters, so skip to the next line. + (format #t "skipping line with NUL characters: ~s\n" line) + (loop (read-line in 'concat))) + (else + (let ((line (fold (lambda (r+p line) + (match r+p + ((regexp . proc) + (match (list-matches regexp line) + ((and m+ (_ _ ...)) + (proc line m+)) + (_ line))))) + line + rx+proc))) + (display line out) + (loop (read-line in 'concat)))))))))) (define-syntax let-matches -- 2.15.1