Doxygen: Empty string in PREDEFINED throws

Created on 6 Jun 2020  路  3Comments  路  Source: doxygen/doxygen

Describe the bug
Our nightly documentation build with the master branch of doxygen encountered following error:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid

A bit of debugging revealed that this line causes the throw:
https://github.com/doxygen/doxygen/blob/f49f1c8cdd9babbbe0350c9ad3d3a3e92244085e/src/configimpl.l#L1105
result.data() is a nullptr and the construction of a std:string from a nullptr throws.

You can add some asserts to see that substEnvVarsInString causes the nullptr to be there.

https://github.com/doxygen/doxygen/blob/f49f1c8cdd9babbbe0350c9ad3d3a3e92244085e/src/configimpl.l#L1048-L1050

    // here we strip the quote again
    assert(result.data() != nullptr);
    substEnvVarsInString(result);
    assert(result.data() != nullptr);

The second assert will throw.

Enabling the debug output in substEnvVarsInString shows that after multiple variables, the string "" is parsed and the result is a nullptr.

This allowed me to figure out that our PREDEFINED is the cause of the error:

PREDEFINED             = "CEREAL_SERIALIZE_FUNCTION_NAME=serialize" \
                         "CEREAL_LOAD_FUNCTION_NAME=load" \
                         "CEREAL_SAVE_FUNCTION_NAME=save" \
                         "CEREAL_LOAD_MINIMAL_FUNCTION_NAME=load_minimal" \
                         "CEREAL_SAVE_MINIMAL_FUNCTION_NAME=save_minimal" \
                         "SEQAN3_DOXYGEN_ONLY(x)= x" \
                         ""

(Note that the "" here is the result of a variable that might be expanded to some actual string in our CMake setup.)

Expected behavior
Just ignore empty strings (like before).

To Reproduce
example.tar.gz

This is a standard Doxfile where the PREDEFINED field contains an empty string:

PREDEFINED             = ""

Version
f49f1c8cdd9babbbe0350c9ad3d3a3e92244085e
(occurring since 0df1623c9363d52a2b04457233dcf2c64319b03c)

Stack trace

libc.so.6!raise (Unknown Source:0)
libc.so.6!abort (Unknown Source:0)
libstdc++.so.6![Unknown/Just-In-Time compiled code] (Unknown Source:0)
libstdc++.so.6!std::terminate() (Unknown Source:0)
libstdc++.so.6!__cxa_throw (Unknown Source:0)
libstdc++.so.6!std::__throw_logic_error(char const*) (Unknown Source:0)
libstdc++.so.6!void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (Unknown Source:0)
substEnvVarsInStrList(StringVector & sl) (doxygen\build\src\configimpl.l:1105)
ConfigList::substEnvVars(ConfigList * const this) (doxygen\build\src\configimpl.l:1118)
ConfigImpl::substituteEnvironmentVars(ConfigImpl * const this) (doxygen\build\src\configimpl.l:1144)
Config::postProcess(bool clearHeaderAndFooter, bool compare) (doxygen\build\src\configimpl.l:1985)
checkConfiguration() (doxygen\src\doxygen.cpp:10266)
main(int argc, char ** argv) (doxygen\src\main.cpp:35)
bug

All 3 comments

Thanks for the stack trace and analysis.
I personally think that the entry should not appear but as it can happen it is better to filter it out (doxygen should definitely not crash).

I've just pushed a proposed patch, pull request #7834.

Code has been integrated in master on github.

Thanks for the quick patch! Can confirm it also works with our setup.

Was this page helpful?
0 / 5 - 0 ratings