Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signaling a simple error would signal another error if the message happened to have a ~ in it #41

Closed
wants to merge 1 commit into from

Conversation

Projects
None yet
2 participants
@alanruttenberg
Copy link
Collaborator

commented Apr 25, 2017

since in simple cases there are no format args, but format is called with the message string. I searched for all cases in the source where there were calls to setFormatControl(x) followed by setFormatArguments(NIL). In such cases I changed setFormatControl(x) -> setFormatControl(x.replaceAll("~","~~")). An example that would trigger the double error was compiling (defun foo (x) ("This should be quoted ~a" x)).

Signaling an simple error would signal another error if the message h…
…appened to have a ~ in it, since in simple cases there are no format args, but format is called with the message string. I searched for all cases in the source where there were calls to setFormatControl(x) followed by setFormatArguments(NIL). In such cases I changed setFormatControl(x) -> setFormatControl(x.replaceAll("~","~~")). An example that would trigger the double error was compiling (defun foo (x) ("This should be quoted ~a" x)).
@easye

This comment has been minimized.

Copy link
Collaborator

commented Apr 26, 2017

While, I think I understand what sort of behavior you are trying to address here, I can't seem to see a "before and after" difference.

Could you please expand on the test case?

The test form as you wrote it

 (defun foo (x) ("This should be quoted ~a" x))

doesn't compile, but doesn't seem to give a "double error" either with or without this changeset applied.

I tried to guess at how to otherwise trigger the double error:

  (handler-case 
      (signal (make-condition 'simple-error :format-control "This should be quoted ~"))
    (t (e)
      (format nil "~a" e))))

but this seems to sensibly return

error in format: String ended before directive was found.
  This should be quoted ~
                        ^

Can you help my understanding here by refining the test case to trigger the double error please?

@alanruttenberg

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 26, 2017

Try (funcall '("This should be quoted ~a" x))

@alanruttenberg

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 26, 2017

Put this:

(defun foo (x) (funcall x))

into a file. Compile and load the file in slime.

(funcall '~) 

I think that should work, or

(setf (symbol-plist '~) (list 1))(remprop '~ '~)

You can tell there will be problems just looking at the code.
https://github.com/armedbear/abcl/blob/master/src/org/armedbear/lisp/Lisp.java#L2037
The ProgramError constructor uses the single argument method, which sets format args to nil. But embedded in the error string is the name of an arbitrary symbol, which could include "~".

The problem was noticed while debugging in slime. The error shown was a format error. After some consternation I realized that it was a program-error that was the problem - I wasn't calling format in the code. I then looked at code for ProgramError, realized that it was buggy, and chose this as a solution. The alternative was tracking down any case that might embed a tilde and fixing it at the source, but that wouldn't protect against future transgression.

@easye

This comment has been minimized.

Copy link
Collaborator

commented Apr 27, 2017

Replication recipe for posterity:

Place the following in a <file:~/work/abcl/double-error.lisp>

(defun foo (x) (funcall x))

then

CL-USER> (compile-file "~/work/abcl/double-error") 
; Compiling /Users/evenson/work/abcl/double-error.lisp ...
; (DEFUN FOO ...)
; Wrote /Users/evenson/work/abcl/double-error.abcl (0.015 seconds)
#P"/Users/evenson/work/abcl/double-error.abcl"
NIL
NIL
CL-USER> (foo '~)

gives

Error (FORMAT-ERROR) during printing: #<PROGRAM-ERROR {264F63C5}>
   [Condition of type PROGRAM-ERROR]

easye pushed a commit that referenced this pull request Apr 27, 2017

mevenson@1c010e3e-69d0-11dd-93a8-456734b0d56f
Fix signalling simple error with #\~ in format string
(Alan Ruttenberg)

Signaling an simple error would signal another error if the message
happened to have a ~ in it, since in simple cases there are no format
args, but format is called with the message string.

We fix this by changing all cases in the source where there were calls
to setFormatControl(x) are followed by setFormatArguments(NIL). In
such cases we changed setFormatControl(x) ->
setFormatControl(x.replaceAll("~","~~")), which is the CL:FORMAT
recipe for escaping a #\~ character.

To replicate this error, place the following in a file
<file:~/work/abcl/double-error.lisp>.

    (defun foo (x) (funcall x))

then

    CL-USER> (compile-file "~/work/abcl/double-error")
    ; Compiling /Users/evenson/work/abcl/double-error.lisp ...
    ; (DEFUN FOO ...)
    ; Wrote /Users/evenson/work/abcl/double-error.abcl (0.015 seconds)
    #P"/Users/evenson/work/abcl/double-error.abcl"
    NIL
    NIL
    CL-USER> (foo '~)

gives

    Error (FORMAT-ERROR) during printing: #<PROGRAM-ERROR {264F63C5}>
       [Condition of type PROGRAM-ERROR]

Merges <#41>.
@easye

This comment has been minimized.

Copy link
Collaborator

commented Apr 27, 2017

Merged with 6b5d59d

@easye easye closed this Apr 27, 2017

svn2github pushed a commit to svn2github/abcl that referenced this pull request Apr 27, 2017

mevenson
Fix signalling simple error with #\~ in format string
(Alan Ruttenberg)

Signaling an simple error would signal another error if the message
happened to have a ~ in it, since in simple cases there are no format
args, but format is called with the message string.

We fix this by changing all cases in the source where there were calls
to setFormatControl(x) are followed by setFormatArguments(NIL). In
such cases we changed setFormatControl(x) ->
setFormatControl(x.replaceAll("~","~~")), which is the CL:FORMAT
recipe for escaping a #\~ character.

To replicate this error, place the following in a file
<file:~/work/abcl/double-error.lisp>.

    (defun foo (x) (funcall x))

then

    CL-USER> (compile-file "~/work/abcl/double-error")
    ; Compiling /Users/evenson/work/abcl/double-error.lisp ...
    ; (DEFUN FOO ...)
    ; Wrote /Users/evenson/work/abcl/double-error.abcl (0.015 seconds)
    #P"/Users/evenson/work/abcl/double-error.abcl"
    NIL
    NIL
    CL-USER> (foo '~)

gives

    Error (FORMAT-ERROR) during printing: #<PROGRAM-ERROR {264F63C5}>
       [Condition of type PROGRAM-ERROR]

Merges <armedbear/abcl#41>.

git-svn-id: http://abcl.org/svn@15001 1c010e3e-69d0-11dd-93a8-456734b0d56f

slyrus pushed a commit to slyrus/abcl that referenced this pull request May 3, 2017

mevenson
Fix signalling simple error with #\~ in format string
(Alan Ruttenberg)

Signaling an simple error would signal another error if the message
happened to have a ~ in it, since in simple cases there are no format
args, but format is called with the message string.

We fix this by changing all cases in the source where there were calls
to setFormatControl(x) are followed by setFormatArguments(NIL). In
such cases we changed setFormatControl(x) ->
setFormatControl(x.replaceAll("~","~~")), which is the CL:FORMAT
recipe for escaping a #\~ character.

To replicate this error, place the following in a file
<file:~/work/abcl/double-error.lisp>.

    (defun foo (x) (funcall x))

then

    CL-USER> (compile-file "~/work/abcl/double-error")
    ; Compiling /Users/evenson/work/abcl/double-error.lisp ...
    ; (DEFUN FOO ...)
    ; Wrote /Users/evenson/work/abcl/double-error.abcl (0.015 seconds)
    #P"/Users/evenson/work/abcl/double-error.abcl"
    NIL
    NIL
    CL-USER> (foo '~)

gives

    Error (FORMAT-ERROR) during printing: #<PROGRAM-ERROR {264F63C5}>
       [Condition of type PROGRAM-ERROR]

Merges <armedbear/abcl#41>.

git-svn-id: http://abcl.org/svn/trunk/abcl@15001 1c010e3e-69d0-11dd-93a8-456734b0d56f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.