Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
326 changes: 325 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,320 @@ PROG_YAJL

AM_CONDITIONAL([YAJL_VERSION], [test "$YAJL_VERSION" != ""])

AC_ARG_WITH([json-c],
[AS_HELP_STRING([--with-json-c=auto|yyjson|json-c|jansson|cjson|none],
[Select the C JSON backend (default: auto)])],
[with_json_c="$withval"], [with_json_c="auto"])

AC_ARG_WITH([json-cxx],
[AS_HELP_STRING([--with-json-cxx=auto|nlohmannjson|jsoncpp|jsoncons|simdjson|glaze|none],
[Select the C++ JSON backend (default: auto)])],
[with_json_cxx="$withval"], [with_json_cxx="auto"])

AC_ARG_WITH([json-prefer],
[AS_HELP_STRING([--with-json-prefer=system|bundled|auto],
[Prefer system or bundled JSON dependencies when both are available (default: auto)])],
[with_json_prefer="$withval"], [with_json_prefer="auto"])

AC_ARG_WITH([json-mode],
[AS_HELP_STRING([--with-json-mode=auto|dom|events],
[Preferred internal JSON mode (default: auto)])],
[with_json_mode="$withval"], [with_json_mode="auto"])

AC_ARG_ENABLE([json-backend-debug],
[AS_HELP_STRING([--enable-json-backend-debug],
[Enable JSON backend debug traces and checks])],
[enable_json_backend_debug="$enableval"], [enable_json_backend_debug="no"])

case "x$with_json_prefer" in
xsystem|xbundled|xauto) ;;
*) AC_MSG_ERROR([Invalid value for --with-json-prefer: $with_json_prefer]) ;;
esac

case "x$with_json_mode" in
xauto|xdom|xevents) ;;
*) AC_MSG_ERROR([Invalid value for --with-json-mode: $with_json_mode]) ;;
esac

JSON_BACKEND_CFLAGS=""
JSON_BACKEND_LDADD=""
JSON_BACKEND_LDFLAGS=""
JSON_C_BACKEND_SOURCE=""
JSON_CXX_BACKEND_SOURCE=""
JSON_C_BACKEND=""
JSON_CXX_BACKEND="none"

AC_MSG_NOTICE([Resolving C JSON backend (${with_json_c})])
case "x$with_json_c" in
xauto)
_msc_json_c_order="yyjson json-c jansson cjson"
if test "x$with_json_prefer" = "xbundled"; then
if test -f "${srcdir}/third_party/json-c/include/json-c/json.h"; then
JSON_C_BACKEND="json-c"
JSON_C_BACKEND_SOURCE="vendored"
JSON_BACKEND_CFLAGS="-I\$(top_srcdir)/third_party/json-c/include"
fi
fi
for _msc_cand in $_msc_json_c_order; do
if test "x$JSON_C_BACKEND" != "x"; then
break
fi
case "$_msc_cand" in
yyjson)
MSC_CHECK_LIB([YYJSON], [yyjson], [yyjson.h], [yyjson], [])
if test "x$YYJSON_FOUND" = "x1"; then
JSON_C_BACKEND="yyjson"
JSON_BACKEND_CFLAGS="$YYJSON_CFLAGS"
JSON_BACKEND_LDFLAGS="$YYJSON_LDFLAGS"
JSON_BACKEND_LDADD="$YYJSON_LDADD"
JSON_C_BACKEND_SOURCE="system"
fi
;;
json-c)
MSC_CHECK_LIB([JSONC], [json-c], [json-c/json.h], [json-c], [-DWITH_JSON_C])
if test "x$JSONC_FOUND" = "x1"; then
JSON_C_BACKEND="json-c"
JSON_BACKEND_CFLAGS="$JSONC_CFLAGS"
JSON_BACKEND_LDFLAGS="$JSONC_LDFLAGS"
JSON_BACKEND_LDADD="$JSONC_LDADD"
JSON_C_BACKEND_SOURCE="system"
elif test "x$with_json_prefer" != "xsystem" && test -f "${srcdir}/third_party/json-c/include/json-c/json.h"; then
JSON_C_BACKEND="json-c"
JSON_C_BACKEND_SOURCE="vendored"
JSON_BACKEND_CFLAGS="-I\$(top_srcdir)/third_party/json-c/include"
fi
;;
jansson)
MSC_CHECK_LIB([JANSSON], [jansson], [jansson.h], [jansson], [])
if test "x$JANSSON_FOUND" = "x1"; then
JSON_C_BACKEND="jansson"
JSON_BACKEND_CFLAGS="$JANSSON_CFLAGS"
JSON_BACKEND_LDFLAGS="$JANSSON_LDFLAGS"
JSON_BACKEND_LDADD="$JANSSON_LDADD"
JSON_C_BACKEND_SOURCE="system"
fi
;;
cjson)
MSC_CHECK_LIB([CJSON], [libcjson cjson], [cjson/cJSON.h], [cjson], [])
if test "x$CJSON_FOUND" = "x1"; then
JSON_C_BACKEND="cjson"
JSON_BACKEND_CFLAGS="$CJSON_CFLAGS"
JSON_BACKEND_LDFLAGS="$CJSON_LDFLAGS"
JSON_BACKEND_LDADD="$CJSON_LDADD"
JSON_C_BACKEND_SOURCE="system"
fi
;;
esac
done
if test "x$JSON_C_BACKEND" = "x"; then
JSON_C_BACKEND="none"
JSON_C_BACKEND_SOURCE="disabled"
fi
;;
xyyjson|xjson-c|xjansson|xcjson)
_msc_explicit_c="$with_json_c"
if test "x$with_json_prefer" = "xbundled" && test "x$_msc_explicit_c" = "xjson-c"; then
if test -f "${srcdir}/third_party/json-c/include/json-c/json.h"; then
JSON_C_BACKEND="json-c"
JSON_C_BACKEND_SOURCE="vendored"
JSON_BACKEND_CFLAGS="-I\$(top_srcdir)/third_party/json-c/include"
else
AC_MSG_ERROR([Vendored json-c selected but headers missing: third_party/json-c/include/json-c/json.h])
fi
fi
if test "x$JSON_C_BACKEND" = "x"; then
case "$_msc_explicit_c" in
yyjson)
MSC_CHECK_LIB([YYJSON], [yyjson], [yyjson.h], [yyjson], [])
if test "x$YYJSON_FOUND" = "x1"; then
JSON_C_BACKEND="yyjson"
JSON_BACKEND_CFLAGS="$YYJSON_CFLAGS"
JSON_BACKEND_LDFLAGS="$YYJSON_LDFLAGS"
JSON_BACKEND_LDADD="$YYJSON_LDADD"
JSON_C_BACKEND_SOURCE="system"
fi
;;
json-c)
MSC_CHECK_LIB([JSONC], [json-c], [json-c/json.h], [json-c], [-DWITH_JSON_C])
if test "x$JSONC_FOUND" = "x1"; then
JSON_C_BACKEND="json-c"
JSON_BACKEND_CFLAGS="$JSONC_CFLAGS"
JSON_BACKEND_LDFLAGS="$JSONC_LDFLAGS"
JSON_BACKEND_LDADD="$JSONC_LDADD"
JSON_C_BACKEND_SOURCE="system"
elif test "x$with_json_prefer" != "xsystem" && test -f "${srcdir}/third_party/json-c/include/json-c/json.h"; then
JSON_C_BACKEND="json-c"
JSON_C_BACKEND_SOURCE="vendored"
JSON_BACKEND_CFLAGS="-I\$(top_srcdir)/third_party/json-c/include"
fi
;;
jansson)
MSC_CHECK_LIB([JANSSON], [jansson], [jansson.h], [jansson], [])
if test "x$JANSSON_FOUND" = "x1"; then
JSON_C_BACKEND="jansson"
JSON_BACKEND_CFLAGS="$JANSSON_CFLAGS"
JSON_BACKEND_LDFLAGS="$JANSSON_LDFLAGS"
JSON_BACKEND_LDADD="$JANSSON_LDADD"
JSON_C_BACKEND_SOURCE="system"
fi
;;
cjson)
MSC_CHECK_LIB([CJSON], [libcjson cjson], [cjson/cJSON.h], [cjson], [])
if test "x$CJSON_FOUND" = "x1"; then
JSON_C_BACKEND="cjson"
JSON_BACKEND_CFLAGS="$CJSON_CFLAGS"
JSON_BACKEND_LDFLAGS="$CJSON_LDFLAGS"
JSON_BACKEND_LDADD="$CJSON_LDADD"
JSON_C_BACKEND_SOURCE="system"
fi
;;
esac
fi
if test "x$JSON_C_BACKEND" = "x"; then
AC_MSG_ERROR([Requested C JSON backend '$with_json_c' is not available with current --with-json-prefer=${with_json_prefer}.])
fi
;;
xnone)
JSON_C_BACKEND="none"
JSON_C_BACKEND_SOURCE="disabled"
;;
*)
AC_MSG_ERROR([Invalid value for --with-json-c: $with_json_c])
;;
esac

case "x$JSON_C_BACKEND" in
xyyjson) JSON_C_BACKEND_DEFINE="-DMSC_JSON_C_BACKEND_YYJSON" ;;
xjson-c) JSON_C_BACKEND_DEFINE="-DMSC_JSON_C_BACKEND_JSONC" ;;
xjansson) JSON_C_BACKEND_DEFINE="-DMSC_JSON_C_BACKEND_JANSSON" ;;
xcjson) JSON_C_BACKEND_DEFINE="-DMSC_JSON_C_BACKEND_CJSON" ;;
xnone) JSON_C_BACKEND_DEFINE="-DMSC_JSON_C_BACKEND_NONE" ;;
esac
if test "x$JSON_C_BACKEND_SOURCE" = "xsystem"; then
JSON_C_BACKEND_DEFINE="$JSON_C_BACKEND_DEFINE -DMSC_JSON_C_BACKEND_SYSTEM"
elif test "x$JSON_C_BACKEND_SOURCE" = "xvendored"; then
JSON_C_BACKEND_DEFINE="$JSON_C_BACKEND_DEFINE -DMSC_JSON_C_BACKEND_VENDORED"
fi

AC_MSG_NOTICE([Resolving C++ JSON backend (${with_json_cxx})])
JSON_CXX_BACKEND="none"
JSON_CXX_BACKEND_SOURCE="disabled"
case "x$with_json_cxx" in
xauto)
if test "x$with_json_prefer" = "xbundled" && test -f "${srcdir}/third_party/nlohmann_json/include/nlohmann/json.hpp"; then
JSON_CXX_BACKEND="nlohmannjson"
JSON_CXX_BACKEND_SOURCE="vendored"
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS -I\$(top_srcdir)/third_party/nlohmann_json/include"
fi
if test "x$JSON_CXX_BACKEND" = "xnone"; then
AC_CHECK_HEADER([simdjson.h], [JSON_CXX_BACKEND="simdjson"; JSON_CXX_BACKEND_SOURCE="system"])
fi
if test "x$JSON_CXX_BACKEND" = "xnone"; then
AC_CHECK_HEADER([nlohmann/json.hpp], [JSON_CXX_BACKEND="nlohmannjson"; JSON_CXX_BACKEND_SOURCE="system"])
fi
if test "x$JSON_CXX_BACKEND" = "xnone"; then
AC_CHECK_HEADER([jsoncons/json.hpp], [JSON_CXX_BACKEND="jsoncons"; JSON_CXX_BACKEND_SOURCE="system"])
fi
if test "x$JSON_CXX_BACKEND" = "xnone"; then
AC_CHECK_HEADER([json/json.h], [JSON_CXX_BACKEND="jsoncpp"; JSON_CXX_BACKEND_SOURCE="system"])
fi
if test "x$JSON_CXX_BACKEND" = "xnone"; then
AC_CHECK_HEADER([glaze/glaze.hpp], [JSON_CXX_BACKEND="glaze"; JSON_CXX_BACKEND_SOURCE="system"])
fi
if test "x$JSON_CXX_BACKEND" = "xnone" && test "x$with_json_prefer" != "xsystem" && test -f "${srcdir}/third_party/nlohmann_json/include/nlohmann/json.hpp"; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Honor explicit --with-json-cxx backend requests

When an explicit C++ backend is requested (for example --with-json-cxx=jsoncpp) and that backend is not found, this fallback still picks vendored nlohmann if --with-json-prefer is not system. Because third_party/nlohmann_json/include/nlohmann/json.hpp is shipped in-tree, configure succeeds instead of reaching the explicit-request failure path, so builds can silently use a different backend than the one the user asked for.

Useful? React with 👍 / 👎.

JSON_CXX_BACKEND="nlohmannjson"
JSON_CXX_BACKEND_SOURCE="vendored"
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS -I\$(top_srcdir)/third_party/nlohmann_json/include"
fi
;;
xsimdjson|xnlohmannjson|xjsoncons|xjsoncpp|xglaze)
_msc_explicit_cxx="$with_json_cxx"
if test "x$_msc_explicit_cxx" = "xnlohmannjson"; then
if test "x$with_json_prefer" = "xbundled"; then
if test -f "${srcdir}/third_party/nlohmann_json/include/nlohmann/json.hpp"; then
JSON_CXX_BACKEND="nlohmannjson"
JSON_CXX_BACKEND_SOURCE="vendored"
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS -I\$(top_srcdir)/third_party/nlohmann_json/include"
else
AC_MSG_ERROR([Vendored nlohmann/json selected but header missing: third_party/nlohmann_json/include/nlohmann/json.hpp])
fi
fi
if test "x$JSON_CXX_BACKEND" = "xnone"; then
AC_CHECK_HEADER([nlohmann/json.hpp], [JSON_CXX_BACKEND="nlohmannjson"; JSON_CXX_BACKEND_SOURCE="system"])
fi
if test "x$JSON_CXX_BACKEND" = "xnone" && test "x$with_json_prefer" != "xsystem" && test -f "${srcdir}/third_party/nlohmann_json/include/nlohmann/json.hpp"; then
JSON_CXX_BACKEND="nlohmannjson"
JSON_CXX_BACKEND_SOURCE="vendored"
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS -I\$(top_srcdir)/third_party/nlohmann_json/include"
fi
elif test "x$_msc_explicit_cxx" = "xsimdjson"; then
AC_CHECK_HEADER([simdjson.h], [JSON_CXX_BACKEND="simdjson"; JSON_CXX_BACKEND_SOURCE="system"])
elif test "x$_msc_explicit_cxx" = "xjsoncons"; then
AC_CHECK_HEADER([jsoncons/json.hpp], [JSON_CXX_BACKEND="jsoncons"; JSON_CXX_BACKEND_SOURCE="system"])
elif test "x$_msc_explicit_cxx" = "xjsoncpp"; then
AC_CHECK_HEADER([json/json.h], [JSON_CXX_BACKEND="jsoncpp"; JSON_CXX_BACKEND_SOURCE="system"])
elif test "x$_msc_explicit_cxx" = "xglaze"; then
AC_CHECK_HEADER([glaze/glaze.hpp], [JSON_CXX_BACKEND="glaze"; JSON_CXX_BACKEND_SOURCE="system"])
fi
if test "x$JSON_CXX_BACKEND" = "xnone"; then
AC_MSG_ERROR([Requested C++ JSON backend '$with_json_cxx' is not available with current --with-json-prefer=${with_json_prefer}.])
fi
;;
xnone)
;;
*)
AC_MSG_ERROR([Invalid value for --with-json-cxx: $with_json_cxx])
;;
esac

case "x$JSON_CXX_BACKEND" in
xsimdjson) JSON_CXX_BACKEND_DEFINE="-DMSC_JSON_CXX_BACKEND_SIMDJSON" ;;
xnlohmannjson) JSON_CXX_BACKEND_DEFINE="-DMSC_JSON_CXX_BACKEND_NLOHMANNJSON" ;;
xjsoncons) JSON_CXX_BACKEND_DEFINE="-DMSC_JSON_CXX_BACKEND_JSONCONS" ;;
xjsoncpp) JSON_CXX_BACKEND_DEFINE="-DMSC_JSON_CXX_BACKEND_JSONCPP" ;;
xglaze) JSON_CXX_BACKEND_DEFINE="-DMSC_JSON_CXX_BACKEND_GLAZE" ;;
*) JSON_CXX_BACKEND_DEFINE="-DMSC_JSON_CXX_BACKEND_NONE" ;;
esac
if test "x$JSON_CXX_BACKEND_SOURCE" = "xsystem"; then
JSON_CXX_BACKEND_DEFINE="$JSON_CXX_BACKEND_DEFINE -DMSC_JSON_CXX_BACKEND_SYSTEM"
elif test "x$JSON_CXX_BACKEND_SOURCE" = "xvendored"; then
JSON_CXX_BACKEND_DEFINE="$JSON_CXX_BACKEND_DEFINE -DMSC_JSON_CXX_BACKEND_VENDORED"
fi

if test "x$JSON_C_BACKEND" != "xnone"; then
AC_DEFINE([WITH_JSON_SUPPORT], [1], [Define if a JSON backend is enabled for JSON generation])
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS $JSON_C_BACKEND_DEFINE $JSON_CXX_BACKEND_DEFINE -DWITH_JSON_SUPPORT"
Comment on lines +397 to +410

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep JSON support enabled when YAJL is the only backend

This gate disables WITH_JSON_SUPPORT whenever JSON_C_BACKEND resolves to none, but the new resolver never includes YAJL in its C-backend candidates. In environments that only have YAJL (a common existing setup), --with-json-c=auto now resolves to none, so Transaction::toJSON and ModSecurity::processContentOffset are compiled out and return the "not compiled with JSON support" path despite YAJL being present. That is a functional regression from the previous YAJL-based JSON generation behavior.

Useful? React with 👍 / 👎.

else
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS $JSON_C_BACKEND_DEFINE $JSON_CXX_BACKEND_DEFINE"
fi

AC_SUBST([JSON_BACKEND_CFLAGS])
AC_SUBST([JSON_BACKEND_LDADD])
AC_SUBST([JSON_BACKEND_LDFLAGS])
AC_SUBST([JSON_C_BACKEND])
AC_SUBST([JSON_C_BACKEND_SOURCE])
AC_SUBST([JSON_CXX_BACKEND])
AC_SUBST([JSON_CXX_BACKEND_SOURCE])
AC_SUBST([JSON_PREFER_MODE], [$with_json_prefer])
AC_SUBST([JSON_OPERATING_MODE], [$with_json_mode])

if test "x$enable_json_backend_debug" = "xyes"; then
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS -DMSC_JSON_BACKEND_DEBUG=1"
AC_DEFINE([MSC_JSON_BACKEND_DEBUG], [1], [Define to enable JSON backend debug logging])
fi

case "x$with_json_mode" in
xdom)
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS -DMSC_JSON_MODE_DOM=1"
;;
xevents)
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS -DMSC_JSON_MODE_EVENTS=1"
;;
*)
JSON_BACKEND_CFLAGS="$JSON_BACKEND_CFLAGS -DMSC_JSON_MODE_AUTO=1"
;;
esac

# Check for LibGeoIP
PROG_GEOIP

Expand Down Expand Up @@ -452,6 +766,17 @@ fi

MSC_STATUS_LIB([LibCURL ], [CURL])
MSC_STATUS_LIB([YAJL ], [YAJL])
echo " + JSON C backend ....${JSON_C_BACKEND} (${JSON_C_BACKEND_SOURCE})"
echo " + JSON C++ backend ....${JSON_CXX_BACKEND} (${JSON_CXX_BACKEND_SOURCE})"
echo " + JSON backend ....${JSON_C_BACKEND} (${JSON_C_BACKEND_SOURCE})"
echo " + JSON C++ backend (effective) ....${JSON_CXX_BACKEND} (${JSON_CXX_BACKEND_SOURCE})"
echo " + JSON preference ....${with_json_prefer}"
echo " + JSON mode ....${with_json_mode}"
if test "x$enable_json_backend_debug" = "xyes"; then
echo " + JSON backend debug ....enabled"
else
echo " + JSON backend debug ....disabled"
fi
MSC_STATUS_LIB([LMDB ], [LMDB])
MSC_STATUS_LIB([LibXML2 ], [LIBXML2])
MSC_STATUS_LIB([SSDEEP ], [SSDEEP])
Expand Down Expand Up @@ -532,4 +857,3 @@ if test "$aflFuzzer" = "true"; then
echo " $ export CC=afl-clang-fast "
echo " "
fi

12 changes: 12 additions & 0 deletions docs/json-backends/autotools-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Moved documentation
# Verschobene Dokumentation

## English
This document moved. Please see:
- `docs/json-backends/build.md`
- `docs/json-backends/backends/`

## Deutsch
Dieses Dokument wurde verschoben. Siehe:
- `docs/json-backends/build.md`
- `docs/json-backends/backends/`
12 changes: 12 additions & 0 deletions docs/json-backends/backend-cjson.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Moved documentation
# Verschobene Dokumentation

## English
This document moved. Please see:
- `docs/json-backends/build.md`
- `docs/json-backends/backends/`

## Deutsch
Dieses Dokument wurde verschoben. Siehe:
- `docs/json-backends/build.md`
- `docs/json-backends/backends/`
12 changes: 12 additions & 0 deletions docs/json-backends/backend-glaze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Moved documentation
# Verschobene Dokumentation

## English
This document moved. Please see:
- `docs/json-backends/build.md`
- `docs/json-backends/backends/`

## Deutsch
Dieses Dokument wurde verschoben. Siehe:
- `docs/json-backends/build.md`
- `docs/json-backends/backends/`
12 changes: 12 additions & 0 deletions docs/json-backends/backend-jansson.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Moved documentation
# Verschobene Dokumentation

## English
This document moved. Please see:
- `docs/json-backends/build.md`
- `docs/json-backends/backends/`

## Deutsch
Dieses Dokument wurde verschoben. Siehe:
- `docs/json-backends/build.md`
- `docs/json-backends/backends/`
Loading