galkahana / HummusJS

Node.js module for high performance creation, modification and parsing of PDF files and streams
http://www.pdfhummus.com
Other
1.14k stars 169 forks source link

Fix segfault to allow tests running on Linux with electron 5 #401

Closed julianhille closed 4 years ago

julianhille commented 5 years ago

This is only a draft PR showing the cause of the segmentation fault. There are several things which are beyond me and i try to document how i achieved testing / seeing the issue.

First of all i created a vagarnt image based on trusty64 and tried to compile which always lead to an error compiling that the libdbus-1.so.3 has ne version information. So i upgraded to xenial which gave me a good compiled bin.

Now i tried to dig down the electron-mocha path and tried to use strace and gdb. First of all i needed to find out which tests are failing and its:

BasicPNGImagesTest.js fails with a segfault and reducing it to the following:

var pdfWriter = require('../hummus').createWriter(__dirname + '/output/BasicPNGImagesTest.pdf',{log:__dirname + '/output/BasicPNGImagesTest.log'});

        var imageOptions = {transformation:[0.5,0,0,0.5,0,0]}

        var page = pdfWriter.createPage(0,0,595,842);
        pdfWriter.startPageContentContext(page)
            .drawImage(10,200,__dirname+'/TestMaterials/images/png/original.png',imageOptions);
        pdfWriter.writePage(page);
        pdfWriter.end()

But its not only the drawImage function, when digging deeper its root cause is from : createFormXObjectFromPNG which also fails.

Side note: PNG and JPEG tests do the tests differently, JPEG uses the more sophisticated drawing API and PNG the higher level convinience functions.

I installed gdb and printed the command line args:

gdb --args /home/ubuntu/.nvm/versions/node/v11.2.0/lib/node_modules/electron/dist/electron /home/ubuntu/.nvm/versions/node/v11.2.0/lib/node_modules/electron-mocha/lib/main.js ./tests/BasicPNGImagesTest.js

When running the debugger the segfault is in vsprintf.c which confused me that the error message should not be defined.

But in the end when removing the png_longjmp function in deps/PDFWriter/PNGImageHandler.cpp the code is running without a segfault. I did not manage to look into the struct ptr what is happening inside there, but its not a NULL pointer.

Why this is working with an electron 1.8.7 i've no idea.

Anyway the test can not succeed as electron (since ever?) is compiled against a LibPNG 1.2. and the deps have added LibPNG 1.6.x.

This is the output from the test log:

[ 27/06/2019 07:17:35 ] LibPNG Warning: Application was compiled with png.h from libpng-1.6.32
[ 27/06/2019 07:17:35 ] LibPNG Warning: Application  is  running with png.c from libpng-1.2.54
[ 27/06/2019 07:18:17 ] LibPNG Error: Incompatible libpng version in application and library
/home/ubuntu/module/tests/output/BasicPNGImagesTest.log

I tried to downgrade LibPNG, but the API changed so that i've got a bunch of compile errors when exchanging sources.

Edit:

The backtrace from gdb:

#0  0x00007ffff1402cc0 in _IO_vfprintf_internal (s=s@entry=0x7fffffffc410, format=<optimized out>,
    format@entry=0x7fffdd6cc5b1 "LibPNG Error: %s", ap=ap@entry=0x7fffffffc548) at vfprintf.c:1632
#1  0x00007ffff14ca754 in ___vsprintf_chk (
    s=0x7fffdd973e00 <Trace::DefaultTrace()::default_trace> "LibPNG Error: Incompatible libpng version in application and library", flags=1, slen=50001, format=0x7fffdd6cc5b1 "LibPNG Error: %s",
    args=0x7fffffffc548) at vsprintf_chk.c:82
#2  0x00007fffdd56d870 in Trace::TraceToLog(char const*, ...) ()
   from /home/ubuntu/module/binding/hummus.node
#3  0x00007fffdd55caab in HandlePngError(png_struct_def*, char const*) ()
   from /home/ubuntu/module/binding/hummus.node
#4  0x00007fffdd695a63 in png_longjmp () from /home/ubuntu/module/binding/hummus.node
#5  0x00007fffdd55cac2 in HandlePngError(png_struct_def*, char const*) ()
   from /home/ubuntu/module/binding/hummus.node
#6  0x00007fffee319647 in png_error () from /lib/x86_64-linux-gnu/libpng12.so.0
#7  0x00007fffee30e892 in png_create_read_struct_2 () from /lib/x86_64-linux-gnu/libpng12.so.0
#8  0x00007fffee30ea61 in png_create_read_struct () from /lib/x86_64-linux-gnu/libpng12.so.0
#9  0x00007fffdd55d7c8 in CreateFormXObjectForPNGStream(IByteReaderWithPosition*, PDFHummus::DocumentContext*, ObjectsContext*, unsigned long) () from /home/ubuntu/module/binding/hummus.node
#10 0x00007fffdd51dd39 in PDFHummus::DocumentContext::WriteFormForImage(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, unsigned long, PDFParsingOptions const&) () from /home/ubuntu/module/binding/hummus.node
#11 0x00007fffdd51c9dc in PDFHummus::DocumentContext::WritePage(PDFPage*) ()
   from /home/ubuntu/module/binding/hummus.node
#12 0x00007fffdd55a09d in PDFWriter::WritePageAndReturnPageID(PDFPage*) ()
   from /home/ubuntu/module/binding/hummus.node
#13 0x00007fffdd4eaccc in PDFWriterDriver::WritePageAndReturnID(v8::FunctionCallbackInfo<v8::Value> const&) () from /home/ubuntu/module/binding/hummus.node
#14 0x00007fffdd4eae79 in PDFWriterDriver::WritePage(v8::FunctionCallbackInfo<v8::Value> const&) ()
julianhille commented 5 years ago

If somebody is interested in the vagrant file i could add it somewhere. Needs a bit more doc and cleanup but I guess it could help developing / testing on a Linux machine.

julianhille commented 4 years ago

supersed by #410