From 4dcc6067661c261cd9c5663e20b291a7eccaab75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Sat, 19 Jun 2021 22:00:44 +0200 Subject: utils: 'edit-expression' no longer leaks file ports. * guix/utils.scm (edit-expression): Use 'call-with-input-file' to make sure IN gets closed. --- guix/utils.scm | 64 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) (limited to 'guix/utils.scm') diff --git a/guix/utils.scm b/guix/utils.scm index 19990ceb8a..a13b13c4fa 100644 --- a/guix/utils.scm +++ b/guix/utils.scm @@ -342,38 +342,40 @@ a list of command-line arguments passed to the compression program." be a procedure that takes the original expression in string and returns a new one. ENCODING will be used to interpret all port I/O, it default to UTF-8. This procedure returns #t on success." + (define file (assq-ref source-properties 'filename)) + (define line (assq-ref source-properties 'line)) + (define column (assq-ref source-properties 'column)) + (with-fluids ((%default-port-encoding encoding)) - (let* ((file (assq-ref source-properties 'filename)) - (line (assq-ref source-properties 'line)) - (column (assq-ref source-properties 'column)) - (in (open-input-file file)) - ;; The start byte position of the expression. - (start (begin (while (not (and (= line (port-line in)) - (= column (port-column in)))) - (when (eof-object? (read-char in)) - (error (format #f "~a: end of file~%" in)))) - (ftell in))) - ;; The end byte position of the expression. - (end (begin (read in) (ftell in)))) - (seek in 0 SEEK_SET) ; read from the beginning of the file. - (let* ((pre-bv (get-bytevector-n in start)) - ;; The expression in string form. - (str (iconv:bytevector->string - (get-bytevector-n in (- end start)) - (port-encoding in))) - (post-bv (get-bytevector-all in)) - (str* (proc str))) - ;; Verify the edited expression is still a scheme expression. - (call-with-input-string str* read) - ;; Update the file with edited expression. - (with-atomic-file-output file - (lambda (out) - (put-bytevector out pre-bv) - (display str* out) - ;; post-bv maybe the end-of-file object. - (when (not (eof-object? post-bv)) - (put-bytevector out post-bv)) - #t)))))) + (call-with-input-file file + (lambda (in) + (let* ( ;; The start byte position of the expression. + (start (begin (while (not (and (= line (port-line in)) + (= column (port-column in)))) + (when (eof-object? (read-char in)) + (error (format #f "~a: end of file~%" in)))) + (ftell in))) + ;; The end byte position of the expression. + (end (begin (read in) (ftell in)))) + (seek in 0 SEEK_SET) ; read from the beginning of the file. + (let* ((pre-bv (get-bytevector-n in start)) + ;; The expression in string form. + (str (iconv:bytevector->string + (get-bytevector-n in (- end start)) + (port-encoding in))) + (post-bv (get-bytevector-all in)) + (str* (proc str))) + ;; Verify the edited expression is still a scheme expression. + (call-with-input-string str* read) + ;; Update the file with edited expression. + (with-atomic-file-output file + (lambda (out) + (put-bytevector out pre-bv) + (display str* out) + ;; post-bv maybe the end-of-file object. + (when (not (eof-object? post-bv)) + (put-bytevector out post-bv)) + #t)))))))) ;;; -- cgit v1.2.3