Wilfred / suggest.el

discover elisp functions that do what you want
367 stars 14 forks source link

Example from readme segfaults Emacs #37

Closed Fuco1 closed 7 years ago

Fuco1 commented 7 years ago

When I try this example

;; Inputs (one per line):
"foo bar"

;; Desired output:
"Foo Bar"

;; Suggestions:
(capitalize "foo bar") ;=> "Foo Bar"

it crashes my emacs. Also many other examples involving strings seem to do so. Is there something like unbound recursion or maybe I overflow the stack? I don't know if it is possible to control that somehow.

My max-lisp-eval-depth was set to 1000, version GNU Emacs 24.5.1 (x86_64-unknown-linux-gnu)

Rising it to 10000 or even 100000 makes no difference.

Wilfred commented 7 years ago

Aha, I can replicate this on 24.5, but not on 25.3. Interestingly, "foo" -> "Foo" is fine.

Suggest.el doesn't use much recursion, it's pretty much a bunch of nested loops. I have max-lisp-eval-depth set to 800 and it's fine.

I suspect there's another function (implemented in C) somewhere that is not robust against inputs of the wrong type, similar to #16.

Fuco1 commented 7 years ago

Yea, I use 25.2 at home but an older version at my work computer. I guess this is not really high priority (25+ has been out for ages now), but an interesting issue nonetheless.

Wilfred commented 7 years ago

The relevant backtrace:

#0  0x000000000051dceb in readbyte_from_string (c=<optimized out>, readcharfun=<optimized out>) at lread.c:498
#1  0x000000000051e572 in readchar (readcharfun=27014838, multibyte=0x7fffffffb45f) at lread.c:322
#2  0x00000000005211a7 in read1 (readcharfun=27014838, pch=0x7fffffffb4ac, first_in_list=false) at lread.c:2487
#3  0x0000000000522650 in read0 (readcharfun=<optimized out>) at lread.c:2156
#4  0x00000000005226e9 in read_internal_start (stream=27014838, start=<optimized out>, end=<optimized out>) at lread.c:2129
#5  0x0000000000500b3f in Ffuncall (nargs=<optimized out>, args=0x7fffffffb600) at eval.c:2811
#6  0x0000000000501c22 in Fapply (nargs=2, args=0x7fffffffb600) at eval.c:2297
#7  0x0000000000500192 in eval_sub (form=<optimized out>) at eval.c:2154
#8  0x0000000000500365 in Fprogn (body=25862742) at eval.c:462
#9  0x0000000000500028 in eval_sub (form=<optimized out>) at eval.c:2131
#10 0x0000000000500294 in Fsetq (args=<optimized out>) at eval.c:539
#11 Fsetq (args=<optimized out>) at eval.c:525
#12 0x0000000000500028 in eval_sub (form=<optimized out>) at eval.c:2131
#13 0x0000000000500365 in Fprogn (body=25860422) at eval.c:462
#14 0x0000000000500028 in eval_sub (form=<optimized out>) at eval.c:2131
#15 0x0000000000502fb1 in internal_lisp_condition_case (var=11479922, bodyform=25860406, handlers=<optimized out>) at eval.c:1317
#16 0x0000000000500028 in eval_sub (form=<optimized out>) at eval.c:2131
#17 0x0000000000500365 in Fprogn (body=25859478) at eval.c:462
#18 0x0000000000503351 in Flet (args=25859158) at eval.c:970
#19 0x0000000000500028 in eval_sub (form=<optimized out>) at eval.c:2131
#20 0x0000000000500365 in Fprogn (body=25859110) at eval.c:462
#21 0x0000000000500028 in eval_sub (form=<optimized out>) at eval.c:2131
#22 0x0000000000500028 in eval_sub (form=<optimized out>) at eval.c:2131
#23 0x0000000000500365 in Fprogn (body=25858902) at eval.c:462
#24 0x0000000000500696 in funcall_lambda (fun=25858534, nargs=3, arg_vector=0x7fffffffbea0) at eval.c:3037
#25 0x00000000004ffa0b in apply_lambda (fun=25858518, args=<optimized out>, count=38) at eval.c:2919
#26 0x00000000004ffd0a in eval_sub (form=<optimized out>) at eval.c:2256
#27 0x000000000050323d in Flet (args=25887350) at eval.c:940
#28 0x0000000000500028 in eval_sub (form=<optimized out>) at eval.c:2131
#29 0x0000000000500365 in Fprogn (body=25887318) at eval.c:462
#30 0x0000000000503351 in Flet (args=25909686) at eval.c:970
#31 0x0000000000500028 in eval_sub (form=<optimized out>) at eval.c:2131
#32 0x0000000000500365 in Fprogn (body=25909558) at eval.c:462
#33 0x0000000000500696 in funcall_lambda (fun=25909462, nargs=4, arg_vector=0x7fffffffc370) at eval.c:3037
Wilfred commented 7 years ago

It's calling read. Minimal example:

(suggest--call 'read '((102 111 111 32 98 97 114 nil)) nil)

Struggling to minimise it further.

Wilfred commented 7 years ago

Fixed. I didn't get as small a reproducing example as I wanted, nor did I find the relevant upstream Emacs bug. Suggest.el avoids segfaulting Emacs 24 at least.