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;

Reply via email to