From 972ab4ebe38803a62c9f942cba5a82e2365babe3 Mon Sep 17 00:00:00 2001 From: Richard M Kreuter Date: Sun, 16 Dec 2007 00:23:59 +0000 Subject: [PATCH] 1.0.12.34: fix bug, add error signalling in RUN-PROGRAM * Incorrect initialization of one bookkeeping variable in COPY-DESCRIPTOR-TO-STREAM left another bookkeeping variable with garbage after a properly-encoded short read, causing subsequent decoding attempts to fail. Only easily visible on when the child line buffers to one or another descriptor. * Add test for same. * Additionally, signal an error if we have any not-yet-decoded octets when the child closes its output or error. * Add test for same. --- src/code/run-program.lisp | 6 +++++- tests/run-program.test.sh | 20 ++++++++++++++++++++ version.lisp-expr | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/code/run-program.lisp b/src/code/run-program.lisp index d4f64370b..1be271f8c 100644 --- a/src/code/run-program.lisp +++ b/src/code/run-program.lisp @@ -879,6 +879,10 @@ Users Manual for details about the PROCESS structure."#-win32" (setf handler nil) (decf (car cookie)) (sb-unix:unix-close descriptor) + (unless (zerop read-end) + ;; Should this be an END-OF-FILE? + (error "~@" buf)) (return)) ((null count) (sb-sys:remove-fd-handler handler) @@ -890,7 +894,7 @@ Users Manual for details about the PROCESS structure."#-win32" (strerror errno))) (t (incf read-end count) - (let* ((decode-end (length buf)) + (let* ((decode-end read-end) (string (handler-case (octets-to-string buf :end read-end diff --git a/tests/run-program.test.sh b/tests/run-program.test.sh index 50e12f31c..beb6e4290 100644 --- a/tests/run-program.test.sh +++ b/tests/run-program.test.sh @@ -82,6 +82,26 @@ ${SBCL:-sbcl} <<'EOF' :input i :output stream))))) (assert (= (length string) 6)) (assert (string= string "abcdef"))) + + ;;; Test the bookkeeping involved in decoding the child's output: + + ;; repeated short, properly-encoded reads exposed one bug. (But + ;; note: this test will be inconclusive if the child's stderr is + ;; fully buffered.) + (let ((str (with-output-to-string (s) + (run-program "/bin/sh" + '("-c" "(echo Foo; sleep 2s; echo Bar)>&2") + :output s :search t :error :output :wait t)))) + (assert (string= str (format nil "Foo~%Bar~%")))) + + ;; end of file in the middle of a UTF-8 character + (typep (nth-value 1 (ignore-errors + (let ((sb-impl::*default-external-format* :utf-8)) + (with-output-to-string (s) + (run-program "printf" '("\\316") + :output s :search t :wait t))))) + 'error) + ;; success convention for this Lisp program run as part of a larger script (sb-ext:quit :unix-status 52))) EOF diff --git a/version.lisp-expr b/version.lisp-expr index 5666f7f54..eec166335 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.12.33" +"1.0.12.34" -- 2.11.4.GIT