hotfuzz
hotfuzz copied to clipboard
Segfault in c module on invalid characters with consult-buffer
Consult apparently tags strings with invalid character; see https://www.reddit.com/r/emacs/comments/n43mdo/problem_with_narrowing_minibuffer_items_with/
Minimal example: (hotfuzz--filter-c "tet" (list (concat "test" (char-to-string #x200000))))
Thanks for reporting this issue. It is caused by the code not handling errors raised by copy_string_contents
due to strings not being representable as valid UTF-8. This should of course be fixed, but the larger issue is that there is no way at all for dynamic modules to access non-UTF-8 Emacs Lisp string values.
I am now using this code:
(defadvice! hotfuzz--filter-c-simple-string (orig-fun string candidates &optional ignore-case)
:around #'hotfuzz--filter-c
(with-demoted-errors "Error in hotfuzz--filter-c-simple-string: %S"
(let*
(
(table (make-hash-table :test #'eq :size (length candidates)))
(cands
(--keep
(when (stringp it)
(let ((encoded (encode-coding-string it 'no-conversion 'nocopy)))
(setf (gethash encoded table) it)
(and (< (length encoded) hotfuzz--max-haystack-len) encoded)))
candidates))
(raw-str (encode-coding-string string 'no-conversion 'nocopy))
(ans
(let
(
(gc-cons-threshold most-positive-fixnum)
(gc-cons-percentage 1.0))
(funcall orig-fun raw-str cands ignore-case))))
(--keep (gethash it table) ans))))
(defadvice! hotfuzz-filter-advice (string _candidates)
:before-while #'hotfuzz-filter
(and
(not (string= string ""))
(< (length (encode-coding-string string 'no-conversion 'nocopy)) hotfuzz--max-needle-len)))
Nonetheless, I get segfaults every so often. ASAN has this to say:
=================================================================
==291197==ERROR: AddressSanitizer: requested allocation size 0x7ffebec61f28 (0x7ffebec62f28 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0x10000000000 (thread T0)
#0 0x7f4f0aa23867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7f4efb9d3acb in bump_alloc /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:155
#2 0x7f4efb9d3acb in copy_emacs_string /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:185
#3 0x7f4efb9d4b35 in hotfuzz_filter /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:288
#4 0x55fed5e6d459 in funcall_module ../../emacs_src/src/emacs-module.c:1183
#5 0x55fed5e30d86 in Ffuncall ../../emacs_src/src/eval.c:2995
==291197==HINT: if you don't care about these errors you may set allocator_may_return_null=1
SUMMARY: AddressSanitizer: allocation-size-too-big ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145 in __interceptor_malloc
==291197==ABORTING
Miraculously I have yet to get a segfault/error under ASAN + allocator_may_return_null=1
if this helps
(gdb) frame 13
#13 copy_emacs_string (env=0x7fffffffad60, bump=0x7fffffffabb0, value=<optimized out>)
at /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:185
185 if (!(result = bump_alloc(bump, sizeof *result + len
(gdb) print **bump
$1 = {next = 0x62d001220400, index = 6984, capacity = 65536, b = 0x63100170c818 "\230\032&\002\020b"}
(gdb) print len
$2 = <optimized out>
(gdb) print value
$3 = <optimized out>
(gdb) frame 14
#14 0x00007fffe84e4b36 in hotfuzz_filter (env=0x7fffffffad60, nargs=<optimized out>, args=<optimized out>, data_ptr=<optimized out>)
at /home/alan/.emacs.d/elpaca/repos/hotfuzz/hotfuzz-module.c:288
288 if (!(b->xs[b->len++].s = copy_emacs_string(env, &bump, value)))
(gdb) print value
$4 = <optimized out>
(gdb) print list
$5 = (emacs_value) 0x6210022601b8
(gdb) print env->is_not_nil(env, list)
$6 = false
See also #12 and #13
This should now be fixed by commits f91c0972cc8887f8e2a123feb96bb5120d2b77c3 and 622329477d893a9fc2528a75935cfe1f8614f4bc.