Hi!
I've just debugged a segfault I encountered with texinfo-6.1 on
NetBSD-7.99.26/amd64 when translating some files that lilypond-2.18.2
provides
(http://download.linuxaudio.org/lilypond/sources/v2.18/lilypond-2.18.2.tar.gz).
It happens in makeinfo. When running gdb on perl I see this:
(gdb) r /usr/pkg/bin/makeinfo --enable-encoding --error-limit=0 -I ./out -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/Documentation/snippets/out -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/Documentation/included -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/Documentation/pictures -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/Documentation -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/input/regression -I. -I./out
--output=out/lilypond-internals.info out/internals.texi
Starting program: /usr/pkg/bin/perl /usr/pkg/bin/makeinfo --enable-encoding
--error-limit=0 -I ./out -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/Documentation/snippets/out -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/Documentation/included -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/Documentation/pictures -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/Documentation -I
/usr/pkgsrc/print/lilypond/work/lilypond-2.18.2/input/regression -I. -I./out
--output=out/lilypond-internals.info out/internals.texi
./common-macros.itexi:190: warning: @end ifset should only appear at a line
beginning
out/internals.texi:9511: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:9512: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:11371: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:11372: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:13430: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:13431: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:15666: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:15667: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:18207: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:18727: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:18728: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:21368: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:21369: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:24102: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:24559: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:24560: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:25396: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:28332: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:28333: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:28547: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:30368: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:31388: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:33283: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:33472: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:33551: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:35364: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:38958: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:39060: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:40819: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:42120: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:42438: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:43193: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:44931: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:44966: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:46691: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:46701: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:46747: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:46747: warning: @vindex should only appear at a line
beginning (possibly involving @rextend)
out/internals.texi:46764: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:47596: warning: @vindex should only appear at a line
beginning (possibly involving @rinternals)
out/internals.texi:47870: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
out/internals.texi:48319: warning: @vindex should only appear at a line
beginning (possibly involving @ruser)
Program received signal SIGSEGV, Segmentation fault.
[Switching to LWP 1]
0x00007f7ff69153cf in memcpy () from /usr/lib/libc.so.12
(gdb) bt
#0 0x00007f7ff69153cf in memcpy () from /usr/lib/libc.so.12
#1 0x00007f7ff34070ff in text_append_n () from
/usr/pkg/lib/texinfo/XSParagraph.so
#2 0x00007f7ff340696e in xspara_add_text () from
/usr/pkg/lib/texinfo/XSParagraph.so
#3 0x00007f7ff3403cc1 in
XS_Texinfo__Convert__XSParagraph__XSParagraph_add_text () from
/usr/pkg/lib/texinfo/XSParagraph.so
#4 0x00007f7ff78d53b1 in Perl_pp_entersub () from
/usr/pkg/lib/perl5/5.22.0/x86_64-netbsd-thread-multi/CORE/libperl.so
#5 0x00007f7ff78ce295 in Perl_runops_standard () from
/usr/pkg/lib/perl5/5.22.0/x86_64-netbsd-thread-multi/CORE/libperl.so
#6 0x00007f7ff78598c2 in perl_run () from
/usr/pkg/lib/perl5/5.22.0/x86_64-netbsd-thread-multi/CORE/libperl.so
#7 0x0000000000401175 in main ()
(gdb)
I tracked this down to code that calls mbrlen but doesn't check its
return value, which might be -1. In the case I see, it indeed is -1 --
and that gets passed as argument to realloc (which is fine, because it
reduces the buffer size) and then memcpy, which breaks.
I've attached the patch I use locally. Please check if the handling of
-1 looks reasonable.
I've also fixed two typos in comments while there.
Cheers,
Thomas
$NetBSD: patch-tp_Texinfo_Convert_XSParagraph_xspara.c,v 1.1 2016/03/20
19:09:53 wiz Exp $
Do not call text_append_n with (size_t)-1.
--- tp/Texinfo/Convert/XSParagraph/xspara.c.orig 2016-01-23
11:31:17.000000000 +0000
+++ tp/Texinfo/Convert/XSParagraph/xspara.c
@@ -872,7 +872,7 @@ xspara_add_text (char *text)
{
if (state.space_counter > 0)
{
- /* Truncuate to at most 2 spaces, and replace
any
+ /* Truncate to at most 2 spaces, and replace any
'\n' or '\r' characters with ' '. */
TEXT new_space;
@@ -892,12 +892,18 @@ xspara_add_text (char *text)
break;
len = mbrlen (pspace, pspace_left, NULL);
- /* Subtitute newlines in the pending space
+ /* Substitute newlines in the pending space
with spaces. */
if (*pspace == '\n' || *pspace == '\r')
text_append_n (&new_space, " ", 1);
- else
- text_append_n (&new_space, pspace, len);
+ else {
+ if (len > 0) {
+ text_append_n (&new_space, pspace, len);
+ } else {
+ /* skip one character and try again */
+ len = 1;
+ }
+ }
state.space_counter++;
pspace += len;