diff --git a/ChangeLog b/ChangeLog index 2146f9e0..169be4f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2021-02-10 Jay Berkenbilt + * Require a C++-14 compiler. + * Detect loops when adding when reading outlines dictionary upon initialization of QPDFOutlineDocumentHelper (fuzz issue 30507). diff --git a/README-maintainer b/README-maintainer index 901c7dd6..a4840603 100644 --- a/README-maintainer +++ b/README-maintainer @@ -4,16 +4,16 @@ ROUTINE DEVELOPMENT Default: -./configure CXX="g++ --std=c++11" --enable-werror +./configure CXX="g++ --std=c++14" --enable-werror Debugging: -./configure CXX="g++ --std=c++11" CFLAGS="-g" CXXFLAGS="-g" \ +./configure CXX="g++ --std=c++14" CFLAGS="-g" CXXFLAGS="-g" \ --enable-werror --disable-shared Profiling: -./configure CXX="g++ --std=c++11" CFLAGS="-g -pg" CXXFLAGS="-g -pg" \ +./configure CXX="g++ --std=c++14" CFLAGS="-g -pg" CXXFLAGS="-g -pg" \ LDFLAGS="-pg" --enable-werror --disable-shared Then run `gprof gmon.out`. Note that gmon.out is not cumulative. @@ -23,7 +23,7 @@ Memory checks: ./configure CFLAGS="-fsanitize=address -fsanitize=undefined -g" \ CXXFLAGS="-fsanitize=address -fsanitize=undefined -g" \ LDFLAGS="-fsanitize=address -fsanitize=undefined" \ - CC=clang CXX="clang++ --std=c++11" \ + CC=clang CXX="clang++ --std=c++14" \ --enable-werror --disable-shared diff --git a/README.md b/README.md index 646091ec..9a59ba9c 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Versions of qpdf prior to version 7 were released under the terms of version 2.0 # Prerequisites -QPDF requires a C++ compiler that supports C++-11. +QPDF requires a C++ compiler that supports C++-14. QPDF depends on the external libraries [zlib](https://www.zlib.net/) and [jpeg](https://www.ijg.org/files/). The [libjpeg-turbo](https://libjpeg-turbo.org/) library is also known to work since it is compatible with the regular jpeg library, and QPDF doesn't use any interfaces that aren't present in the straight jpeg8 API. These are part of every Linux distribution and are readily available. Download information appears in the documentation. For Windows, you can download pre-built binary versions of these libraries for some compilers; see [README-windows.md](README-windows.md) for additional details. diff --git a/autofiles.sums b/autofiles.sums index 42f0e9e2..16b5c850 100644 --- a/autofiles.sums +++ b/autofiles.sums @@ -1,6 +1,6 @@ -acefdeee8c37c7cabad528c8984440d96036da4af81050a02fbcca7a9d3c2922 configure.ac +715dae6d625977752bf7ddf7e386a2dc6ada04b8e56c6f0e7a3f7dcc9bad3209 configure.ac d3f9ee6f6f0846888d9a10fd3dad2e4b1258be84205426cf04d7cef02d61dad7 aclocal.m4 -cf2c764639c4c94abc183a0976eca6ae500b80790ea25e3d0af97b23587363b7 libqpdf/qpdf/qpdf-config.h.in +d12e9b7b928e7b2b9d4ffbc2af170392421376e60e40d07bdeee6a7252be8f6e libqpdf/qpdf/qpdf-config.h.in 5297971a0ef90bcd5563eb3f7127a032bb76d3ae2af7258bf13479caf8983a60 m4/ax_cxx_compile_stdcxx.m4 35bc5c645dc42d47f2daeea06f8f3e767c8a1aee6a35eb2b4854fd2ce66c3413 m4/ax_random_device.m4 1451e63710701b5f00a668f3a79b435015ef2e63547f0ad0ce8c8c062d53b599 m4/libtool.m4 diff --git a/build-scripts/test-sanitizers b/build-scripts/test-sanitizers index 476f198a..38170575 100755 --- a/build-scripts/test-sanitizers +++ b/build-scripts/test-sanitizers @@ -7,7 +7,7 @@ sudo apt-get -y install \ CFLAGS="-fsanitize=address -fsanitize=undefined -g" \ CXXFLAGS="-fsanitize=address -fsanitize=undefined -g" \ LDFLAGS="-fsanitize=address -fsanitize=undefined" \ - CC=clang CXX="clang++ --std=c++11" \ + CC=clang CXX="clang++ --std=c++14" \ --enable-crypto-native --enable-crypto-openssl --enable-crypto-gnutls \ --enable-werror --disable-shared --enable-show-failed-test-output make -j$(nproc) -k diff --git a/configure b/configure index e1111989..5a043128 100755 --- a/configure +++ b/configure @@ -710,7 +710,7 @@ AS EGREP GREP CPP -HAVE_CXX11 +HAVE_CXX14 ac_ct_CXX CXXFLAGS CXX @@ -4055,7 +4055,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu - ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true + ax_cxx_compile_alternatives="14 1y" ax_cxx_compile_cxx14_required=true ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4068,9 +4068,9 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do for switch in "" -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do - cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 -$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } + cachevar=`$as_echo "ax_cv_cxx_compile_cxx14_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++14 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++14 features with $switch... " >&6; } if eval \${$cachevar+:} false; then : $as_echo_n "(cached) " >&6 else @@ -4366,6 +4366,126 @@ namespace cxx11 + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L && ! defined(_MSC_VER) + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + + + _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval $cachevar=yes @@ -4398,19 +4518,19 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu - if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ax_cxx_compile_cxx14_required = xtrue; then if test x$ac_success = xno; then - as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + as_fn_error $? "*** A compiler with support for C++14 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then - HAVE_CXX11=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 -$as_echo "$as_me: No compiler with C++11 support was found" >&6;} + HAVE_CXX14=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++14 support was found" >&5 +$as_echo "$as_me: No compiler with C++14 support was found" >&6;} else - HAVE_CXX11=1 + HAVE_CXX14=1 -$as_echo "#define HAVE_CXX11 1" >>confdefs.h +$as_echo "#define HAVE_CXX14 1" >>confdefs.h fi diff --git a/configure.ac b/configure.ac index 935e4fd7..fd349a66 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,7 @@ fi AC_PROG_CC AC_PROG_CC_C99 AC_PROG_CXX -AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory]) +AX_CXX_COMPILE_STDCXX([14], [noext], [mandatory]) AC_HEADER_STDC LT_INIT([win32-dll]) diff --git a/libqpdf/qpdf/qpdf-config.h.in b/libqpdf/qpdf/qpdf-config.h.in index 2a279d6a..bee4cc49 100644 --- a/libqpdf/qpdf/qpdf-config.h.in +++ b/libqpdf/qpdf/qpdf-config.h.in @@ -6,8 +6,8 @@ /* Default crypto provider */ #undef DEFAULT_CRYPTO -/* define if the compiler supports basic C++11 syntax */ -#undef HAVE_CXX11 +/* define if the compiler supports basic C++14 syntax */ +#undef HAVE_CXX14 /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml index 6885aff6..c14d0bdf 100644 --- a/manual/qpdf-manual.xml +++ b/manual/qpdf-manual.xml @@ -118,7 +118,7 @@ - A C++ compiler that supports C++-11. + A C++ compiler that supports C++-14. @@ -5186,6 +5186,21 @@ print "\n"; + + + Build Changes + + + + + A C++-14 compiler is now required to build qpdf. There is no + intention to require anything newer than that for a while. + C++-14 includes modest enhancements to C++-11 and appears to + be supported about as widely as C++-11. + + + + Bug Fixes