Subject: bug#15984: 24.3; Problem with combining characters in attachment filename

From: [email-masked] (Niels Möller)
Date: Thu, 28 Nov 2013 09:08:54 +0100

I'm reading email with Gnus. I received an email with an attachment
containing the headers

  Content-Type: application/pdf;
   name="Brev =?UTF-8?B?YWt0aWVhzIhnYXIgMTMxMTI3LnBkZg==?="
  Content-Transfer-Encoding: base64
  Content-Disposition: attachment;
   filename*0*=UTF-8''%42%72%65%76%20%61%6B%74%69%65%61%CC%88%67%61%72%20%31;
   filename*1*=%33%31%31%32%37%2E%70%64%66

Apparently sent by a Mac user,

  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:24.0) Gecko/20100101 Thunderbird/24.1.1

The attachement was displayed in the *Article* buffer as

  [2. application/pdf; Brev aktiea?gar 131127.pdf]...

I was running emacs-24.3 in a tty, in a latin-1 locale, on a sparc
Solaris system. (In a latin-1 tty, emacs ought to display "ä" instead of
"a?", but that's a less severe and possibly unrelated problem).

  SunOS bacon 5.10 Generic_147147-26 sun4u sparc SUNW,Sun-Fire-15000

When I tried to save the attachment by pressing "o" on that button
(gnus-mime-save-part), emacs immediately crashed with a segmentation
violation signal. Since emacs very rarely crashes, I was a bit
surprised. I just restarted emacs and Gnus and tried again, and it
crashed again. So at least for me, the problem is reproducible.

And a crash triggered by untrusted data in a received email is always
scary. After fixing the bug, exploit possibilities ought to be analyzed.

The gdb backtrace, based on the generated core file, looks like this:

(gdb) bt
#0  0xfec4ebd4 in _lwp_kill () from /lib/libc.so.1
#1  0xfebe7bb8 in raise () from /lib/libc.so.1
#2  0x000e7f78 in terminate_due_to_signal ()
#3  0x00103d04 in handle_fatal_signal ()
#4  0x001037d0 in deliver_thread_signal ()
#5  0xfec4b014 in __sighndlr () from /lib/libc.so.1
#6  0xfec3f6c4 in call_user_handler () from /lib/libc.so.1
#7  <signal handler called>
#8  0x000b5748 in char_table_ref ()
#9  0x001ad54c in composition_compute_stop_pos ()
#10 0x001266ec in scan_for_column ()
#11 0x00127328 in current_column ()
#12 0x00114cec in read_minibuf ()
#13 0x00115688 in Fread_from_minibuffer ()
#14 0x0015c538 in Ffuncall ()
#15 0x00190de0 in exec_byte_code ()
#16 0x0015c368 in Ffuncall ()
#17 0x001158a0 in Fcompleting_read ()
#18 0x0015c4e4 in Ffuncall ()
#19 0x00190de0 in exec_byte_code ()
#20 0x0015c368 in Ffuncall ()
#21 0x00190de0 in exec_byte_code ()
#22 0x0015c368 in Ffuncall ()
#23 0x00190de0 in exec_byte_code ()
#24 0x0015bf18 in funcall_lambda ()
#25 0x0015c368 in Ffuncall ()
#26 0x00190de0 in exec_byte_code ()
#27 0x0015bf18 in funcall_lambda ()
#28 0x0015c368 in Ffuncall ()
#29 0x0015cbf0 in apply1 ()
#30 0x001573b4 in Fcall_interactively ()
#31 0x0015c574 in Ffuncall ()
#32 0x0015c77c in call3 ()
#33 0x000f0ac0 in Fcommand_execute ()
#34 0x000f829c in command_loop_1 ()
#35 0x001591dc in internal_condition_case ()
#36 0x000ea2a0 in command_loop_2 ()
#37 0x001590c0 in internal_catch ()
#38 0x000ea11c in recursive_edit_1 ()
#39 0x000ea264 in Frecursive_edit ()
#40 0x000e9b28 in main ()

The emacs binary I use appear to have been stripped, so bt full gives
no additional information, and xbacktrace fails with

  No symbol "CHECK_LISP_OBJECT_TYPE" in current context.

If I decode the base-64 part of the Content-type "name" value, I get

  $ od -tx1c fname.txt 
  0000000  61  6b  74  69  65  61  cc  88  67  61  72  20  31  33  31  31
            a   k   t   i   e   a 314 210   g   a   r       1   3   1   1
  0000020  32  37  2e  70  64  66
            2   7   .   p   d   f
  0000026

So it appears to contain the character "ä" (a with two dots), coded as
"a" followed by a unicode combining character. All in utf-8. If I run
cat fname.txt in xterm with a utf-8 locale, it displays the string as
"aktieägar 131127.pdf", which seems correct.

I don't understand the meaning of the Content-disposition: header, but I
guess it's possible that Content-type: ...; name= *is* processed
correctly, and it's the code processing Content-disposition which
crashes. But looking at the backtrace, it looks like the problem is
related to handling of combining characters.

Below is the info generated by report-emacs-bug, except that I deleted
recent input and recent messages, since the problem was in the emacs
process which crashed, not in this one where I'm composing this message.
Environment should otherwise be identical (same emacs, same Gnus, same
machine, same tty).

Regards,
/Niels

In GNU Emacs 24.3.1 (sparc-sun-solaris2.10, X toolkit, Xaw scroll bars)
 of 2013-03-15 on stalhein
Configured using:
 `configure '--prefix=/pkg/emacs/sparc-sol10/24.3' '--with-gif=no'
 '--with-jpeg=no' '--with-tiff=no' '--with-png=no' '--with-dbus=no'
 '--with-gsettings=no' '--with-gnutls=no' 'CC=gcc' 'CFLAGS=-O2 -mcpu=v9'
 'LDFLAGS=-L/usr/local/lib -R/usr/local/lib'
 'CPPFLAGS=-I/usr/local/include''

Important settings:
  value of $LC_COLLATE: C
  value of $LC_CTYPE: sv_SE.ISO8859-1
  value of $LC_MESSAGES: C
  value of $LC_MONETARY: en_US.ISO8859-1
  value of $LC_NUMERIC: en_US.ISO8859-1
  value of $LC_TIME: en_US.ISO8859-1
  locale-coding-system: iso-latin-1-unix
  default enable-multibyte-characters: t

Major mode: Summary

Minor modes in effect:
  type-break-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  buffer-read-only: t
  line-number-mode: t
  transient-mark-mode: t

Recent input: [omitted]

Recent messages: [omitted]

Features:
(shadow emacsbug help-mode sort ansi-color gnus-cite flow-fill
mm-archive mail-extr gnus-async gnus-bcklg qp parse-time gnus-ml
disp-table misearch multi-isearch gnus-topic byte-opt bytecomp
byte-compile cconv nndraft nnmh nnml gnus-agent gnus-srvr gnus-score
score-mode nnvirtual gnus-msg gnus-art mm-uu mml2015 epg-config mm-view
mml-smime smime password-cache dig mailcap nntp gnus-cache gnus-sum nnoo
gnus-group gnus-undo nnmail mail-source gnus-start gnus-spec gnus-int
gnus-range message sendmail format-spec rfc822 mml mml-sec mm-decode
mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 ietf-drums
mailabbrev gmm-utils mailheader gnus-win gnus gnus-ems nnheader
gnus-util mail-utils mm-util mail-prsvr wid-edit bbdb-autoloads package
cl-macs gv bookmark pp recurse cl time-date type-break uniquify advice
help-fns cl-lib advice-preload info easymenu tooltip ediff-hook vc-hooks
lisp-float-type mwheel x-win x-dnd tool-bar dnd fontset image regexp-opt
fringe tabulated-list newcomment lisp-mode register page menu-bar
rfn-eshadow timer select scroll-bar mouse jit-lock font-lock syntax
facemenu font-core frame cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese hebrew greek romanian slovak
czech european ethiopic indian cyrillic chinese case-table epa-hook
jka-cmpr-hook help simple abbrev minibuffer loaddefs button faces
cus-face macroexp files text-properties overlay sha1 md5 base64 format
env code-pages mule custom widget hashtable-print-readable backquote
make-network-process dynamic-setting x-toolkit x multi-tty emacs)

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.