Crashes that you can fix! – EasyHack

As discussed in the “crash fixes for LibreOffice, part 1: segfaults“, bugs that lead to crash in LibreOffice or other native applications can have different causes, and therefore need completely different fixes. Some of these bugs are hard to fix: you have to change the behavior of the application in order to avoid crashes.

On the other hand, there are some cases that a fix can be simple checking for a pointer to make sure that it is not NULL/nullptr before actually using it. Or, making sure that a variable has properly initialization before its use. In these cases, fixing the bug is not too hard, and a fix can be provided very quickly.

Example EasyHacks Related to Crashes

Thanks to Mike, this week we have 2 new EasyHacks of this kind:

When accessing uninitialized a TextInputStream, an exception should be thrown, in which leads to Basic run-time error. Instead, because of lack of appropriate checks, it leads to a crash.

You can debug and see the crash point by executing this LibreOffice BASIC code snippet:

Sub crash
  stream = CreateUnoService("com.sun.star.io.TextInputStream")
  stream.available()
End Sub

To fix this bug, one should take a look at OTextInputStream code inside core/io/source/TextInputStream/TextInputStream.cxx:53 and make sure to check and throw runtime exception where appropriate.

This second issue is a crash that happens when parsing an XML with undeclared namespace. To catch and debug such a crash, you should create a tiny xml file as described in the bug report:

<?xml version="1.0" encoding="UTF-8"?>
<a:xml/>

Then, try to parse it with this LibreOffice BASIC script:

Sub Parse
  source = CreateUnoStruct("com.sun.star.xml.sax.InputSource")
  source.aInputStream = CreateUnoService("com.sun.star.ucb.SimpleFileAccess").openFileRead(ConvertToURL("path/to/file.xml"))
  parser = CreateUnoService("com.sun.star.xml.sax.FastParser")
  parser.ParseStream(source)
End Sub

Then, you will see that the crash happens in this part of the code in core/sax/source/fastparser/fastparser.cxx:1281:

if ( !m_bIgnoreMissingNSDecl || URI != nullptr   )
    sNamespace = OUString( XML_CAST( URI ), strlen( XML_CAST( URI )), RTL_TEXTENCODING_UTF8 );

If you look closely, you will understand that if m_bIgnoreMissingNSDecl is false, then the URI check to make sure that it not nullptr is not happening. And dereferencing nullptr leads to crash.

The above two EasyHacks are good for the newcomers. So, if you have some knowledge on C++ and you are able to build LibreOffice, you can work on these issues. If so, first try to gain a basic understanding of the problem. Then assign the bug to yourself and try to fix it.

Writing Tests for Crash Fixes

Writing tests for the crash is also not a very hard task. Either a CppUnitTest, or a UITest can do the exact things that leads to crash without a fix. Then, the test will fail if a crash occurs preventing the same problem in the future.

If you search for “crash” in the LibreOffice commit titles, you can find many good examples of fixing the crashes. As an example that uses CppUnitTest, you can look at this patch:

And for a crash fix with a UITest, you can look at this patch:

Final Notes

EasyHacks are good starting points for the newcomers. If you want to contribute to LibreOffice code by working on this improvement, but you need to know how to get started with LibreOffice development, you can see our video tutorial:

Getting Started (Video Tutorial)