Repository: owasp-modsecurity/ModSecurity Branch: v3/master Commit: 1c1ccf6c6143 Files: 819 Total size: 4.0 MB Directory structure: gitextract_v37w8tr4/ ├── .editorconfig ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug-report-for-version-2-x.md │ │ └── bug-report-for-version-3-x.md │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows/ │ ├── ci.yml │ └── ci_new.yml ├── .gitignore ├── .gitmodules ├── AUTHORS ├── CHANGES ├── LICENSE ├── Makefile.am ├── README.md ├── SECURITY.md ├── build/ │ ├── .empty │ ├── ax_cxx_compile_stdcxx.m4 │ ├── ax_prog_doxygen.m4 │ ├── ax_valgrind_check.m4 │ ├── curl.m4 │ ├── libgeoip.m4 │ ├── libmaxmind.m4 │ ├── libxml.m4 │ ├── lmdb.m4 │ ├── lua.m4 │ ├── msc_find_lib.m4 │ ├── pcre.m4 │ ├── pcre2.m4 │ ├── release.sh │ ├── ssdeep.m4 │ ├── win32/ │ │ ├── CMakeLists.txt │ │ ├── ConfigureChecks.cmake │ │ ├── README.md │ │ ├── conanfile.txt │ │ ├── config.h.cmake │ │ └── docker/ │ │ ├── Dockerfile │ │ ├── InstallBuildTools.cmd │ │ └── git.inf │ └── yajl.m4 ├── build.sh ├── configure.ac ├── doc/ │ ├── .empty │ ├── Makefile.am │ └── doxygen.cfg ├── examples/ │ ├── Makefile.am │ ├── multiprocess_c/ │ │ ├── Makefile.am │ │ ├── basic_rules.conf │ │ └── multi.c │ ├── multithread/ │ │ ├── Makefile.am │ │ ├── basic_rules.conf │ │ └── multithread.cc │ ├── reading_logs_via_rule_message/ │ │ ├── Makefile.am │ │ ├── blocked_request.conf │ │ ├── blocked_request_engine_on.conf │ │ ├── match.conf │ │ ├── no_match.conf │ │ ├── reading_logs_via_rule_message.h │ │ └── simple_request.cc │ ├── reading_logs_with_offset/ │ │ ├── Makefile.am │ │ └── read.cc │ ├── simple_example_using_c/ │ │ ├── Makefile.am │ │ ├── basic_rules.conf │ │ ├── test-valgrind.sh │ │ └── test.c │ └── using_bodies_in_chunks/ │ ├── Makefile.am │ ├── example.conf │ └── simple_request.cc ├── headers/ │ └── modsecurity/ │ ├── actions/ │ │ └── action.h │ ├── anchored_set_variable.h │ ├── anchored_set_variable_translation_proxy.h │ ├── anchored_variable.h │ ├── audit_log.h │ ├── collection/ │ │ ├── collection.h │ │ └── collections.h │ ├── debug_log.h │ ├── intervention.h │ ├── modsecurity.h │ ├── rule.h │ ├── rule_marker.h │ ├── rule_message.h │ ├── rule_unconditional.h │ ├── rule_with_actions.h │ ├── rule_with_operator.h │ ├── rules.h │ ├── rules_exceptions.h │ ├── rules_properties.h │ ├── rules_set.h │ ├── rules_set_phases.h │ ├── rules_set_properties.h │ ├── transaction.h │ ├── variable_origin.h │ └── variable_value.h ├── modsecurity.conf-recommended ├── modsecurity.pc.in ├── others/ │ └── Makefile.am ├── src/ │ ├── Makefile.am │ ├── actions/ │ │ ├── accuracy.cc │ │ ├── accuracy.h │ │ ├── action.cc │ │ ├── audit_log.cc │ │ ├── audit_log.h │ │ ├── block.cc │ │ ├── block.h │ │ ├── capture.cc │ │ ├── capture.h │ │ ├── chain.cc │ │ ├── chain.h │ │ ├── ctl/ │ │ │ ├── audit_engine.cc │ │ │ ├── audit_engine.h │ │ │ ├── audit_log_parts.cc │ │ │ ├── audit_log_parts.h │ │ │ ├── parse_xml_into_args.cc │ │ │ ├── parse_xml_into_args.h │ │ │ ├── request_body_access.cc │ │ │ ├── request_body_access.h │ │ │ ├── request_body_processor_json.cc │ │ │ ├── request_body_processor_json.h │ │ │ ├── request_body_processor_urlencoded.cc │ │ │ ├── request_body_processor_urlencoded.h │ │ │ ├── request_body_processor_xml.cc │ │ │ ├── request_body_processor_xml.h │ │ │ ├── rule_engine.cc │ │ │ ├── rule_engine.h │ │ │ ├── rule_remove_by_id.cc │ │ │ ├── rule_remove_by_id.h │ │ │ ├── rule_remove_by_tag.cc │ │ │ ├── rule_remove_by_tag.h │ │ │ ├── rule_remove_target_by_id.cc │ │ │ ├── rule_remove_target_by_id.h │ │ │ ├── rule_remove_target_by_tag.cc │ │ │ └── rule_remove_target_by_tag.h │ │ ├── data/ │ │ │ ├── status.cc │ │ │ └── status.h │ │ ├── disruptive/ │ │ │ ├── allow.cc │ │ │ ├── allow.h │ │ │ ├── deny.cc │ │ │ ├── deny.h │ │ │ ├── drop.cc │ │ │ ├── drop.h │ │ │ ├── pass.cc │ │ │ ├── pass.h │ │ │ ├── redirect.cc │ │ │ └── redirect.h │ │ ├── exec.cc │ │ ├── exec.h │ │ ├── expire_var.cc │ │ ├── expire_var.h │ │ ├── init_col.cc │ │ ├── init_col.h │ │ ├── log.cc │ │ ├── log.h │ │ ├── log_data.cc │ │ ├── log_data.h │ │ ├── maturity.cc │ │ ├── maturity.h │ │ ├── msg.cc │ │ ├── msg.h │ │ ├── multi_match.cc │ │ ├── multi_match.h │ │ ├── no_audit_log.cc │ │ ├── no_audit_log.h │ │ ├── no_log.cc │ │ ├── no_log.h │ │ ├── phase.cc │ │ ├── phase.h │ │ ├── rev.cc │ │ ├── rev.h │ │ ├── rule_id.cc │ │ ├── rule_id.h │ │ ├── set_env.cc │ │ ├── set_env.h │ │ ├── set_rsc.cc │ │ ├── set_rsc.h │ │ ├── set_sid.cc │ │ ├── set_sid.h │ │ ├── set_uid.cc │ │ ├── set_uid.h │ │ ├── set_var.cc │ │ ├── set_var.h │ │ ├── severity.cc │ │ ├── severity.h │ │ ├── skip.cc │ │ ├── skip.h │ │ ├── skip_after.cc │ │ ├── skip_after.h │ │ ├── tag.cc │ │ ├── tag.h │ │ ├── transformations/ │ │ │ ├── base64_decode.cc │ │ │ ├── base64_decode.h │ │ │ ├── base64_decode_ext.cc │ │ │ ├── base64_decode_ext.h │ │ │ ├── base64_encode.cc │ │ │ ├── base64_encode.h │ │ │ ├── cmd_line.cc │ │ │ ├── cmd_line.h │ │ │ ├── compress_whitespace.cc │ │ │ ├── compress_whitespace.h │ │ │ ├── css_decode.cc │ │ │ ├── css_decode.h │ │ │ ├── escape_seq_decode.cc │ │ │ ├── escape_seq_decode.h │ │ │ ├── hex_decode.cc │ │ │ ├── hex_decode.h │ │ │ ├── hex_encode.cc │ │ │ ├── hex_encode.h │ │ │ ├── html_entity_decode.cc │ │ │ ├── html_entity_decode.h │ │ │ ├── js_decode.cc │ │ │ ├── js_decode.h │ │ │ ├── length.cc │ │ │ ├── length.h │ │ │ ├── lower_case.cc │ │ │ ├── lower_case.h │ │ │ ├── md5.cc │ │ │ ├── md5.h │ │ │ ├── none.cc │ │ │ ├── none.h │ │ │ ├── normalise_path.cc │ │ │ ├── normalise_path.h │ │ │ ├── normalise_path_win.cc │ │ │ ├── normalise_path_win.h │ │ │ ├── parity_even_7bit.cc │ │ │ ├── parity_even_7bit.h │ │ │ ├── parity_odd_7bit.cc │ │ │ ├── parity_odd_7bit.h │ │ │ ├── parity_zero_7bit.cc │ │ │ ├── parity_zero_7bit.h │ │ │ ├── remove_comments.cc │ │ │ ├── remove_comments.h │ │ │ ├── remove_comments_char.cc │ │ │ ├── remove_comments_char.h │ │ │ ├── remove_nulls.cc │ │ │ ├── remove_nulls.h │ │ │ ├── remove_whitespace.cc │ │ │ ├── remove_whitespace.h │ │ │ ├── replace_comments.cc │ │ │ ├── replace_comments.h │ │ │ ├── replace_nulls.cc │ │ │ ├── replace_nulls.h │ │ │ ├── sha1.cc │ │ │ ├── sha1.h │ │ │ ├── sql_hex_decode.cc │ │ │ ├── sql_hex_decode.h │ │ │ ├── transformation.cc │ │ │ ├── transformation.h │ │ │ ├── trim.cc │ │ │ ├── trim.h │ │ │ ├── trim_left.cc │ │ │ ├── trim_left.h │ │ │ ├── trim_right.cc │ │ │ ├── trim_right.h │ │ │ ├── upper_case.cc │ │ │ ├── upper_case.h │ │ │ ├── url_decode.cc │ │ │ ├── url_decode.h │ │ │ ├── url_decode_uni.cc │ │ │ ├── url_decode_uni.h │ │ │ ├── url_encode.cc │ │ │ ├── url_encode.h │ │ │ ├── utf8_to_unicode.cc │ │ │ └── utf8_to_unicode.h │ │ ├── ver.cc │ │ ├── ver.h │ │ ├── xmlns.cc │ │ └── xmlns.h │ ├── anchored_set_variable.cc │ ├── anchored_variable.cc │ ├── audit_log/ │ │ ├── audit_log.cc │ │ └── writer/ │ │ ├── https.cc │ │ ├── https.h │ │ ├── parallel.cc │ │ ├── parallel.h │ │ ├── serial.cc │ │ ├── serial.h │ │ ├── writer.cc │ │ └── writer.h │ ├── collection/ │ │ ├── backend/ │ │ │ ├── collection_data.cc │ │ │ ├── collection_data.h │ │ │ ├── in_memory-per_process.cc │ │ │ ├── in_memory-per_process.h │ │ │ ├── lmdb.cc │ │ │ └── lmdb.h │ │ └── collections.cc │ ├── compat/ │ │ └── msvc.h │ ├── debug_log/ │ │ ├── debug_log.cc │ │ ├── debug_log_writer.cc │ │ └── debug_log_writer.h │ ├── debug_log_writer_agent.h │ ├── engine/ │ │ ├── lua.cc │ │ └── lua.h │ ├── modsecurity.cc │ ├── operators/ │ │ ├── .directory │ │ ├── begins_with.cc │ │ ├── begins_with.h │ │ ├── contains.cc │ │ ├── contains.h │ │ ├── contains_word.cc │ │ ├── contains_word.h │ │ ├── detect_sqli.cc │ │ ├── detect_sqli.h │ │ ├── detect_xss.cc │ │ ├── detect_xss.h │ │ ├── ends_with.cc │ │ ├── ends_with.h │ │ ├── eq.cc │ │ ├── eq.h │ │ ├── fuzzy_hash.cc │ │ ├── fuzzy_hash.h │ │ ├── ge.cc │ │ ├── ge.h │ │ ├── geo_lookup.cc │ │ ├── geo_lookup.h │ │ ├── gsblookup.cc │ │ ├── gsblookup.h │ │ ├── gt.cc │ │ ├── gt.h │ │ ├── inspect_file.cc │ │ ├── inspect_file.h │ │ ├── ip_match.cc │ │ ├── ip_match.h │ │ ├── ip_match_f.cc │ │ ├── ip_match_f.h │ │ ├── ip_match_from_file.cc │ │ ├── ip_match_from_file.h │ │ ├── le.cc │ │ ├── le.h │ │ ├── lt.cc │ │ ├── lt.h │ │ ├── no_match.cc │ │ ├── no_match.h │ │ ├── operator.cc │ │ ├── operator.h │ │ ├── pm.cc │ │ ├── pm.h │ │ ├── pm_f.h │ │ ├── pm_from_file.cc │ │ ├── pm_from_file.h │ │ ├── rbl.cc │ │ ├── rbl.h │ │ ├── rsub.cc │ │ ├── rsub.h │ │ ├── rx.cc │ │ ├── rx.h │ │ ├── rx_global.cc │ │ ├── rx_global.h │ │ ├── str_eq.cc │ │ ├── str_eq.h │ │ ├── str_match.cc │ │ ├── str_match.h │ │ ├── unconditional_match.cc │ │ ├── unconditional_match.h │ │ ├── validate_byte_range.cc │ │ ├── validate_byte_range.h │ │ ├── validate_dtd.cc │ │ ├── validate_dtd.h │ │ ├── validate_hash.cc │ │ ├── validate_hash.h │ │ ├── validate_schema.cc │ │ ├── validate_schema.h │ │ ├── validate_url_encoding.cc │ │ ├── validate_url_encoding.h │ │ ├── validate_utf8_encoding.cc │ │ ├── validate_utf8_encoding.h │ │ ├── verify_cc.cc │ │ ├── verify_cc.h │ │ ├── verify_cpf.cc │ │ ├── verify_cpf.h │ │ ├── verify_ssn.cc │ │ ├── verify_ssn.h │ │ ├── verify_svnr.cc │ │ ├── verify_svnr.h │ │ ├── within.cc │ │ └── within.h │ ├── parser/ │ │ ├── Makefile.am │ │ ├── driver.cc │ │ ├── driver.h │ │ ├── location.hh │ │ ├── position.hh │ │ ├── seclang-parser.cc │ │ ├── seclang-parser.hh │ │ ├── seclang-parser.yy │ │ ├── seclang-scanner.cc │ │ ├── seclang-scanner.ll │ │ └── stack.hh │ ├── request_body_processor/ │ │ ├── json.cc │ │ ├── json.h │ │ ├── multipart.cc │ │ ├── multipart.h │ │ ├── xml.cc │ │ └── xml.h │ ├── rule.cc │ ├── rule_message.cc │ ├── rule_script.cc │ ├── rule_script.h │ ├── rule_unconditional.cc │ ├── rule_with_actions.cc │ ├── rule_with_operator.cc │ ├── rules_exceptions.cc │ ├── rules_set.cc │ ├── rules_set_phases.cc │ ├── rules_set_properties.cc │ ├── run_time_string.cc │ ├── run_time_string.h │ ├── transaction.cc │ ├── unique_id.cc │ ├── unique_id.h │ ├── utils/ │ │ ├── acmp.cc │ │ ├── acmp.h │ │ ├── base64.cc │ │ ├── base64.h │ │ ├── decode.cc │ │ ├── decode.h │ │ ├── geo_lookup.cc │ │ ├── geo_lookup.h │ │ ├── https_client.cc │ │ ├── https_client.h │ │ ├── ip_tree.cc │ │ ├── ip_tree.h │ │ ├── md5.h │ │ ├── msc_tree.cc │ │ ├── msc_tree.h │ │ ├── phase.h │ │ ├── random.cc │ │ ├── random.h │ │ ├── regex.cc │ │ ├── regex.h │ │ ├── sha1.h │ │ ├── shared_files.cc │ │ ├── shared_files.h │ │ ├── string.h │ │ ├── system.cc │ │ └── system.h │ └── variables/ │ ├── args.h │ ├── args_combined_size.h │ ├── args_get.h │ ├── args_get_names.h │ ├── args_names.h │ ├── args_post.h │ ├── args_post_names.h │ ├── auth_type.h │ ├── duration.cc │ ├── duration.h │ ├── env.cc │ ├── env.h │ ├── files.h │ ├── files_combined_size.h │ ├── files_names.h │ ├── files_sizes.h │ ├── files_tmp_content.h │ ├── files_tmp_names.h │ ├── full_request.h │ ├── full_request_length.h │ ├── geo.h │ ├── global.h │ ├── highest_severity.cc │ ├── highest_severity.h │ ├── inbound_data_error.h │ ├── ip.h │ ├── matched_var.h │ ├── matched_var_name.h │ ├── matched_vars.h │ ├── matched_vars_names.h │ ├── modsec_build.cc │ ├── modsec_build.h │ ├── msc_pcre_error.h │ ├── msc_pcre_limits_exceeded.h │ ├── multipart_boundary_quoted.h │ ├── multipart_boundary_whitespace.h │ ├── multipart_crlf_lf_lines.h │ ├── multipart_data_after.h │ ├── multipart_data_before.h │ ├── multipart_file_limit_exceeded.h │ ├── multipart_file_name.h │ ├── multipart_header_folding.h │ ├── multipart_invalid_header_folding.h │ ├── multipart_invalid_part.h │ ├── multipart_invalid_quoting.h │ ├── multipart_lf_line.h │ ├── multipart_missing_semicolon.h │ ├── multipart_name.h │ ├── multipart_part_headers.h │ ├── multipart_strict_error.h │ ├── multipart_unmatched_boundary.h │ ├── outbound_data_error.h │ ├── path_info.h │ ├── query_string.h │ ├── remote_addr.h │ ├── remote_host.h │ ├── remote_port.h │ ├── remote_user.cc │ ├── remote_user.h │ ├── reqbody_error.h │ ├── reqbody_error_msg.h │ ├── reqbody_processor.h │ ├── reqbody_processor_error.h │ ├── reqbody_processor_error_msg.h │ ├── request_base_name.h │ ├── request_body.h │ ├── request_body_length.h │ ├── request_cookies.h │ ├── request_cookies_names.h │ ├── request_file_name.h │ ├── request_headers.h │ ├── request_headers_names.h │ ├── request_line.h │ ├── request_method.h │ ├── request_protocol.h │ ├── request_uri.h │ ├── request_uri_raw.h │ ├── resource.h │ ├── response_body.h │ ├── response_content_length.h │ ├── response_content_type.h │ ├── response_headers.h │ ├── response_headers_names.h │ ├── response_protocol.h │ ├── response_status.h │ ├── rule.cc │ ├── rule.h │ ├── server_addr.h │ ├── server_name.h │ ├── server_port.h │ ├── session.h │ ├── session_id.h │ ├── status.h │ ├── time.cc │ ├── time.h │ ├── time_day.cc │ ├── time_day.h │ ├── time_epoch.cc │ ├── time_epoch.h │ ├── time_hour.cc │ ├── time_hour.h │ ├── time_min.cc │ ├── time_min.h │ ├── time_mon.cc │ ├── time_mon.h │ ├── time_sec.cc │ ├── time_sec.h │ ├── time_wday.cc │ ├── time_wday.h │ ├── time_year.cc │ ├── time_year.h │ ├── tx.cc │ ├── tx.h │ ├── unique_id.h │ ├── url_encoded_error.h │ ├── user.h │ ├── user_id.h │ ├── variable.cc │ ├── variable.h │ ├── web_app_id.h │ ├── xml.cc │ └── xml.h ├── test/ │ ├── .empty │ ├── Makefile.am │ ├── benchmark/ │ │ ├── Makefile.am │ │ ├── basic_rules.conf │ │ ├── benchmark.cc │ │ ├── download-owasp-v3-rules.sh │ │ └── download-owasp-v4-rules.sh │ ├── coding_style_suppressions.txt │ ├── common/ │ │ ├── colors.h │ │ ├── custom_debug_log.cc │ │ ├── custom_debug_log.h │ │ ├── modsecurity_test.cc │ │ ├── modsecurity_test.h │ │ ├── modsecurity_test_context.h │ │ └── modsecurity_test_results.h │ ├── cppcheck_suppressions.txt │ ├── custom-test-driver │ ├── fuzzer/ │ │ ├── Makefile.am │ │ └── afl_fuzzer.cc │ ├── modsecurity-regression-ip-list.txt │ ├── modsecurity-regression-rules.txt │ ├── optimization/ │ │ └── optimization.cc │ ├── regression/ │ │ ├── regression.cc │ │ ├── regression_test.cc │ │ └── regression_test.h │ ├── regression-tests-valgrind.sh │ ├── test-cases/ │ │ ├── data/ │ │ │ ├── GeoIP2-City-Test-source.json │ │ │ ├── GeoIP2-City-Test.mmdb │ │ │ ├── SoapEnvelope-bad.dtd │ │ │ ├── SoapEnvelope-bad.xsd │ │ │ ├── SoapEnvelope.dtd │ │ │ ├── SoapEnvelope.xsd │ │ │ ├── SoapEnvelope2.xsd │ │ │ ├── big-file.conf │ │ │ ├── config_example-bad-op-include.txt │ │ │ ├── config_example-ops-include.txt │ │ │ ├── config_example.txt │ │ │ ├── config_example2.txt │ │ │ ├── config_example3.txt │ │ │ ├── geo/ │ │ │ │ └── README.txt │ │ │ ├── inspectFile-abcdef.lua │ │ │ ├── ipMatchFromFile.txt │ │ │ ├── match-getvar-multi-transformations.lua │ │ │ ├── match-getvar-transformation.lua │ │ │ ├── match-getvar-withTnfs.lua │ │ │ ├── match-getvar.lua │ │ │ ├── match-getvars-args.lua │ │ │ ├── match-getvars.lua │ │ │ ├── match-log.lua │ │ │ ├── match-set.lua │ │ │ ├── match.lua │ │ │ ├── not-so-big-file.conf │ │ │ ├── pattern-file1.data │ │ │ ├── pattern-file2.data │ │ │ ├── script.lua │ │ │ ├── setvar.lua │ │ │ ├── ssdeep.txt │ │ │ ├── test.lua │ │ │ └── unicode.mapping-reduced │ │ └── regression/ │ │ ├── action-allow.json │ │ ├── action-block.json │ │ ├── action-ctl_audit_engine.json │ │ ├── action-ctl_request_body_access.json │ │ ├── action-ctl_request_body_processor.json │ │ ├── action-ctl_request_body_processor_urlencoded.json │ │ ├── action-ctl_rule_engine.json │ │ ├── action-ctl_rule_remove_by_id.json │ │ ├── action-ctl_rule_remove_by_tag.json │ │ ├── action-ctl_rule_remove_target_by_id.json │ │ ├── action-ctl_rule_remove_target_by_tag.json │ │ ├── action-disruptive.json │ │ ├── action-exec.json │ │ ├── action-expirevar.json │ │ ├── action-id.json │ │ ├── action-initcol.json │ │ ├── action-msg.json │ │ ├── action-setenv.json │ │ ├── action-setrsc.json │ │ ├── action-setsid.json │ │ ├── action-setuid.json │ │ ├── action-skip.json │ │ ├── action-tag.json │ │ ├── action-tnf-base64.json │ │ ├── action-xmlns.json │ │ ├── actions.json │ │ ├── auditlog.json │ │ ├── collection-case-insensitive.json │ │ ├── collection-lua.json │ │ ├── collection-regular_expression_selection.json │ │ ├── collection-resource.json │ │ ├── collection-tx-with-macro.json │ │ ├── collection-tx.json │ │ ├── config-body_limits.json │ │ ├── config-calling_phases_by_name.json │ │ ├── config-include-bad.json │ │ ├── config-include.json │ │ ├── config-remove_by_id.json │ │ ├── config-remove_by_msg.json │ │ ├── config-remove_by_tag.json │ │ ├── config-response_type.json │ │ ├── config-secdefaultaction.json │ │ ├── config-secremoterules.json │ │ ├── config-update-action-by-id.json │ │ ├── config-update-target-by-id.json │ │ ├── config-update-target-by-msg.json │ │ ├── config-update-target-by-tag.json │ │ ├── config-xml_external_entity.json │ │ ├── debug_log.json │ │ ├── directive-sec_rule_script.json │ │ ├── fn-setHostname.json │ │ ├── issue-1152.json │ │ ├── issue-1528.json │ │ ├── issue-1565.json │ │ ├── issue-1576.json │ │ ├── issue-1591.json │ │ ├── issue-1725.json │ │ ├── issue-1743.json │ │ ├── issue-1785.json │ │ ├── issue-1812.json │ │ ├── issue-1825.json │ │ ├── issue-1831.json │ │ ├── issue-1844.json │ │ ├── issue-1850.json │ │ ├── issue-1941.json │ │ ├── issue-1943.json │ │ ├── issue-1956.json │ │ ├── issue-1960.json │ │ ├── issue-2000.json │ │ ├── issue-2099.json │ │ ├── issue-2111.json │ │ ├── issue-2196.json │ │ ├── issue-2296.json │ │ ├── issue-2423-msg-in-chain.json │ │ ├── issue-2427.json │ │ ├── issue-3340.json │ │ ├── issue-394.json │ │ ├── issue-849.json │ │ ├── issue-960.json │ │ ├── misc-variable-under-quotes.json │ │ ├── misc.json │ │ ├── offset-variable.json │ │ ├── operator-UnconditionalMatch.json │ │ ├── operator-detectsqli.json │ │ ├── operator-detectxss.json │ │ ├── operator-fuzzyhash.json │ │ ├── operator-inpectFile.json │ │ ├── operator-ipMatchFromFile.json │ │ ├── operator-pm.json │ │ ├── operator-pmfromfile.json │ │ ├── operator-rx.json │ │ ├── operator-rxGlobal.json │ │ ├── operator-validate-byte-range.json │ │ ├── operator-verifycc.json │ │ ├── operator-verifycpf.json │ │ ├── operator-verifyssn.json │ │ ├── operator-verifysvnr.json │ │ ├── request-body-parser-json.json │ │ ├── request-body-parser-multipart-crlf.json │ │ ├── request-body-parser-multipart.json │ │ ├── request-body-parser-xml-validade-dtd.json │ │ ├── request-body-parser-xml.json │ │ ├── rule-920120.json │ │ ├── rule-920200.json │ │ ├── rule-920274.json │ │ ├── sec_component_signature.json │ │ ├── secaction.json │ │ ├── secargumentslimit.json │ │ ├── secmarker.json │ │ ├── secruleengine.json │ │ ├── transformation-none.json │ │ ├── transformations.json │ │ ├── variable-ARGS.json │ │ ├── variable-ARGS_COMBINED_SIZE.json │ │ ├── variable-ARGS_GET.json │ │ ├── variable-ARGS_GET_NAMES.json │ │ ├── variable-ARGS_NAMES.json │ │ ├── variable-ARGS_POST.json │ │ ├── variable-ARGS_POST_NAMES.json │ │ ├── variable-AUTH_TYPE.json │ │ ├── variable-DURATION.json │ │ ├── variable-ENV.json │ │ ├── variable-FILES.json │ │ ├── variable-FILES_COMBINED_SIZE.json │ │ ├── variable-FILES_NAMES.json │ │ ├── variable-FILES_SIZES.json │ │ ├── variable-FULL_REQUEST.json │ │ ├── variable-FULL_REQUEST_LENGTH.json │ │ ├── variable-GEO.json │ │ ├── variable-HIGHEST_SEVERITY.json │ │ ├── variable-INBOUND_DATA_ERROR.json │ │ ├── variable-MATCHED_VAR.json │ │ ├── variable-MATCHED_VARS.json │ │ ├── variable-MATCHED_VARS_NAMES.json │ │ ├── variable-MATCHED_VAR_NAME.json │ │ ├── variable-MODSEC_BUILD.json │ │ ├── variable-MULTIPART_CRLF_LF_LINES.json │ │ ├── variable-MULTIPART_FILENAME.json │ │ ├── variable-MULTIPART_INVALID_HEADER_FOLDING.json │ │ ├── variable-MULTIPART_NAME.json │ │ ├── variable-MULTIPART_PART_HEADERS.json │ │ ├── variable-MULTIPART_STRICT_ERROR.json │ │ ├── variable-MULTIPART_UNMATCHED_BOUNDARY.json │ │ ├── variable-OUTBOUND_DATA_ERROR.json │ │ ├── variable-PATH_INFO.json │ │ ├── variable-QUERY_STRING.json │ │ ├── variable-REMOTE_ADDR.json │ │ ├── variable-REMOTE_HOST.json │ │ ├── variable-REMOTE_PORT.json │ │ ├── variable-REMOTE_USER.json │ │ ├── variable-REQBODY_PROCESSOR.json │ │ ├── variable-REQBODY_PROCESSOR_ERROR.json │ │ ├── variable-REQUEST_BASENAME.json │ │ ├── variable-REQUEST_BODY.json │ │ ├── variable-REQUEST_BODY_LENGTH.json │ │ ├── variable-REQUEST_COOKIES.json │ │ ├── variable-REQUEST_COOKIES_NAMES.json │ │ ├── variable-REQUEST_FILENAME.json │ │ ├── variable-REQUEST_HEADERS.json │ │ ├── variable-REQUEST_HEADERS_NAMES.json │ │ ├── variable-REQUEST_LINE.json │ │ ├── variable-REQUEST_METHOD.json │ │ ├── variable-REQUEST_PROTOCOL.json │ │ ├── variable-REQUEST_URI.json │ │ ├── variable-REQUEST_URI_RAW.json │ │ ├── variable-RESPONSE_BODY.json │ │ ├── variable-RESPONSE_CONTENT_LENGTH.json │ │ ├── variable-RESPONSE_CONTENT_TYPE.json │ │ ├── variable-RESPONSE_HEADERS.json │ │ ├── variable-RESPONSE_HEADERS_NAMES.json │ │ ├── variable-RESPONSE_PROTOCOL.json │ │ ├── variable-RULE.json │ │ ├── variable-SERVER_ADDR.json │ │ ├── variable-SERVER_NAME.json │ │ ├── variable-SERVER_PORT.json │ │ ├── variable-SESSIONID.json │ │ ├── variable-STATUS.json │ │ ├── variable-TIME.json │ │ ├── variable-TIME_DAY.json │ │ ├── variable-TIME_EPOCH.json │ │ ├── variable-TIME_HOUR.json │ │ ├── variable-TIME_MIN.json │ │ ├── variable-TIME_MON.json │ │ ├── variable-TIME_SEC.json │ │ ├── variable-TIME_WDAY.json │ │ ├── variable-TIME_YEAR.json │ │ ├── variable-TX.json │ │ ├── variable-UNIQUE_ID.json │ │ ├── variable-URLENCODED_ERROR.json │ │ ├── variable-USERID.json │ │ ├── variable-WEBAPPID.json │ │ ├── variable-WEBSERVER_ERROR_LOG.json │ │ ├── variable-XML.json │ │ ├── variable-variation-count.json │ │ └── variable-variation-exclusion.json │ ├── test-suite.in │ ├── test-suite.sh │ ├── unit/ │ │ ├── unit.cc │ │ ├── unit_test.cc │ │ └── unit_test.h │ ├── unit-tests-valgrind.sh │ └── valgrind_suppressions.txt ├── tools/ │ ├── Makefile.am │ └── rules-check/ │ ├── Makefile.am │ └── rules-check.cc ├── unicode.mapping └── vcbuild.bat ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ # top-most EditorConfig file root = true # Unix-style newlines with a newline ending every file [*] end_of_line = lf indent_style = space # Scripts without suffixes in the project root tend to indent by two spaces indent_size = 2 # Most of the project files indent by four spaces [*/**] indent_size = 4 # Test files indent by two spaces [test/**] indent_size = 2 # The config parser file indents by both two and four spaces, # so we choose to indent by two spaces as a common denominator. [*.yy] indent_size = 2 [{Makefile,Makefile.am}] indent_style = tab ================================================ FILE: .github/ISSUE_TEMPLATE/bug-report-for-version-2-x.md ================================================ --- name: Bug report for version 2.x about: Create a report to help us improve title: '' labels: '2.x' assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **Logs and dumps** Output of: 1. DebugLogs (level 9) 2. AuditLogs 3. Error logs 4. If there is a crash, the core dump file. _Notice:_ Be carefully to not leak any confidential information. **To Reproduce** Steps to reproduce the behavior: A **curl** command line that mimics the original request and reproduces the problem. Or a ModSecurity v3 test case. [e.g: curl "modsec-full/ca/..\\..\\..\\..\\..\\..\\/\\etc/\\passwd" or [issue-394.json](https://github.com/SpiderLabs/ModSecurity/blob/v3/master/test/test-cases/regression/issue-394.json)] **Expected behavior** A clear and concise description of what you expected to happen. **Server (please complete the following information):** - ModSecurity version (and connector): [e.g. ModSecurity v3.0.1 with nginx-connector v1.0.0] - WebServer: [e.g. nginx-1.15.5] - OS (and distro): [e.g. Linux, archlinux] **Rule Set (please complete the following information):** - Running any public or commercial rule set? [e.g. SpiderLabs commercial rules] - What is the version number? [e.g. 2018-08-11] **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/bug-report-for-version-3-x.md ================================================ --- name: Bug report for version 3.x about: Create a report to help us improve. If you don't know a specific detail or piece of information leave it blank, if necessary we will help you to figure out. title: '' labels: '3.x' assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **Logs and dumps** Output of: 1. DebugLogs (level 9) 2. AuditLogs 3. Error logs 4. If there is a crash, the core dump file. _Notice:_ Be careful to not leak any confidential information. **To Reproduce** Steps to reproduce the behavior: A **curl** command line that mimics the original request and reproduces the problem. Or a ModSecurity v3 test case. [e.g: curl "modsec-full/ca/..\\..\\..\\..\\..\\..\\/\\etc/\\passwd" or [issue-394.json](https://github.com/SpiderLabs/ModSecurity/blob/v3/master/test/test-cases/regression/issue-394.json)] **Expected behavior** A clear and concise description of what you expected to happen. **Server (please complete the following information):** - ModSecurity version (and connector): [e.g. ModSecurity v3.0.8 with nginx-connector v1.0.3] - WebServer: [e.g. nginx-1.18.0] - OS (and distro): [e.g. Linux, archlinux] **Rule Set (please complete the following information):** - Running any public or commercial rule set? [e.g. SpiderLabs commercial rules] - What is the version number? [e.g. 2018-08-11] **Additional context** Add any other context about the problem here. ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## what ## why ## references ================================================ FILE: .github/workflows/ci.yml ================================================ name: Quality Assurance on: push: pull_request: jobs: build-linux: name: Linux (${{ matrix.platform.label }}, ${{ matrix.compiler.label }}, ${{ matrix.configure.label }}) runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-22.04] platform: - {label: "x64", arch: "amd64", configure: ""} - {label: "x32", arch: "i386", configure: "PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32"} compiler: - {label: "gcc", cc: "gcc", cxx: "g++"} - {label: "clang", cc: "clang", cxx: "clang++"} configure: - {label: "with parser generation", opt: "--enable-parser-generation" } - {label: "wo curl", opt: "--without-curl" } - {label: "wo lua", opt: "--without-lua" } - {label: "wo maxmind", opt: "--without-maxmind" } - {label: "wo libxml", opt: "--without-libxml" } - {label: "wo geoip", opt: "--without-geoip" } - {label: "wo ssdeep", opt: "--without-ssdeep" } - {label: "with lmdb", opt: "--with-lmdb" } - {label: "with pcre", opt: "--with-pcre" } exclude: - platform: {label: "x32"} configure: {label: "wo geoip"} - platform: {label: "x32"} configure: {label: "wo ssdeep"} steps: - name: Setup Dependencies (common) run: | sudo dpkg --add-architecture ${{ matrix.platform.arch }} sudo apt-get update -y -qq sudo apt-get install -y libyajl-dev:${{ matrix.platform.arch }} \ libcurl4-openssl-dev:${{ matrix.platform.arch }} \ liblmdb-dev:${{ matrix.platform.arch }} \ liblua5.2-dev:${{ matrix.platform.arch }} \ libmaxminddb-dev:${{ matrix.platform.arch }} \ libpcre2-dev:${{ matrix.platform.arch }} \ pcre2-utils:${{ matrix.platform.arch }} \ bison flex - name: Setup Dependencies (x32) if: ${{ matrix.platform.label == 'x32' }} run: | sudo apt-get install g++-multilib sudo apt-get install -y libxml2-dev:${{ matrix.platform.arch }} \ libpcre3-dev:${{ matrix.platform.arch }} - name: Setup Dependencies (x64) if: ${{ matrix.platform.label == 'x64' }} run: | sudo apt-get install -y libgeoip-dev:${{ matrix.platform.arch }} \ libfuzzy-dev:${{ matrix.platform.arch }} - uses: actions/checkout@v4 with: submodules: true fetch-depth: 0 - name: build.sh run: ./build.sh - name: configure env: CC: ${{ matrix.compiler.cc }} CXX: ${{ matrix.compiler.cxx }} run: ./configure ${{ matrix.platform.configure }} ${{ matrix.configure.opt }} --enable-assertions=yes - uses: ammaraskar/gcc-problem-matcher@master - name: make run: make -j `nproc` - name: check run: make check build-macos: name: macOS (${{ matrix.configure.label }}) runs-on: ${{ matrix.os }} strategy: matrix: os: [macos-14] configure: - {label: "with parser generation", opt: "--enable-parser-generation" } - {label: "wo curl", opt: "--without-curl" } - {label: "wo lua", opt: "--without-lua" } - {label: "wo maxmind", opt: "--without-maxmind" } - {label: "wo libxml", opt: "--without-libxml" } - {label: "wo geoip", opt: "--without-geoip" } - {label: "wo ssdeep", opt: "--without-ssdeep" } - {label: "with lmdb", opt: "--with-lmdb" } - {label: "with pcre", opt: "--with-pcre" } steps: - name: Setup Dependencies # curl, pcre2 not installed because they're already # included in the image run: | brew install autoconf \ automake \ libtool \ yajl \ lmdb \ lua \ libmaxminddb \ libxml2 \ ssdeep \ pcre \ bison \ flex - uses: actions/checkout@v4 with: submodules: true fetch-depth: 0 - name: Build GeoIP run: | git clone --depth 1 --no-checkout https://github.com/maxmind/geoip-api-c.git cd geoip-api-c git fetch --tags # Check out the last release, v1.6.12 git checkout 4b526e7331ca1d692b74a0509ddcc725622ed31a autoreconf --install ./configure --disable-dependency-tracking --disable-silent-rules --prefix=/opt/homebrew make install - name: build.sh run: ./build.sh - name: configure run: ./configure ${{ matrix.configure.opt }} --enable-assertions=yes - uses: ammaraskar/gcc-problem-matcher@master - name: make run: make -j `sysctl -n hw.logicalcpu` - name: check run: make check build-windows: name: Windows (${{ matrix.platform.label }}, ${{ matrix.configure.label }}) runs-on: ${{ matrix.os }} strategy: matrix: os: [windows-2022] platform: - {label: "x64", arch: "x86_64"} configuration: [Release] configure: - {label: "full", opt: "" } - {label: "wo curl", opt: "-DWITH_CURL=OFF" } - {label: "wo lua", opt: "-DWITH_LUA=OFF" } - {label: "wo maxmind", opt: "-DWITH_MAXMIND=OFF" } - {label: "wo libxml", opt: "-DWITH_LIBXML2=OFF" } - {label: "with lmdb", opt: "-DWITH_LMDB=ON" } steps: - uses: actions/checkout@v4 with: submodules: true fetch-depth: 0 - name: Install Conan run: | pip3 install conan --upgrade conan profile detect - uses: ammaraskar/msvc-problem-matcher@master - name: Build ${{ matrix.configuration }} ${{ matrix.platform.arch }} ${{ matrix.configure.label }} shell: cmd run: vcbuild.bat ${{ matrix.configuration }} ${{ matrix.platform.arch }} NO_ASAN "${{ matrix.configure.opt }}" - name: Set up test environment working-directory: build\win32\build\${{ matrix.configuration }} env: BASE_DIR: ..\..\..\.. shell: cmd run: | copy unit_tests.exe %BASE_DIR%\test copy regression_tests.exe %BASE_DIR%\test copy libModSecurity.dll %BASE_DIR%\test copy %BASE_DIR%\unicode.mapping %BASE_DIR%\test md \tmp md \bin copy "C:\Program Files\Git\usr\bin\echo.exe" \bin copy "C:\Program Files\Git\usr\bin\echo.exe" \bin\echo - name: Disable tests that don't work on Windows working-directory: test\test-cases\regression shell: cmd run: | jq "map(if .title == \"Test match variable (1/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json jq "map(if .title == \"Test match variable (2/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json jq "map(if .title == \"Test match variable (3/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json jq "map(if .title == \"Variable offset - FILES_NAMES\" then .enabled = 0 else . end)" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json - name: Run tests working-directory: build\win32\build run: | ctest -C ${{ matrix.configuration }} --output-on-failure cppcheck: runs-on: [macos-14] steps: - name: Setup Dependencies run: | brew install autoconf \ automake \ libtool \ cppcheck - uses: actions/checkout@v4 with: submodules: true fetch-depth: 0 - name: configure run: | ./build.sh ./configure - name: cppcheck run: make check-static ================================================ FILE: .github/workflows/ci_new.yml ================================================ name: Quality Assurance new on: push: pull_request: jobs: build-linux: name: Linux (${{ matrix.platform.label }}, ${{ matrix.compiler.label }}, ${{ matrix.configure.label }}) # Ubuntu 24.04 does not provide native 32-bit (i386) installation images. # Only amd64 (x86_64) is officially supported. 32-bit has been removed from this matrix. runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: platform: - { label: "x64", arch: "amd64", configure: "" } compiler: - { label: "gcc", cc: "gcc", cxx: "g++" } - { label: "clang", cc: "clang", cxx: "clang++" } configure: - { label: "with parser generation", opt: "--enable-parser-generation" } - { label: "without curl", opt: "--without-curl" } - { label: "without lua", opt: "--without-lua" } - { label: "without maxmind", opt: "--without-maxmind" } - { label: "without libxml", opt: "--without-libxml" } - { label: "without geoip", opt: "--without-geoip" } - { label: "without ssdeep", opt: "--without-ssdeep" } - { label: "with lmdb", opt: "--with-lmdb" } - { label: "with pcre2 (default)", opt: "" } - { label: "with pcre", opt: "--with-pcre" } steps: - uses: actions/checkout@v6 with: fetch-depth: 0 submodules: recursive - name: Install dependencies run: | sudo apt-get update -y -qq sudo apt-get install -y \ libyajl-dev \ libcurl4-openssl-dev \ liblmdb-dev \ liblua5.2-dev \ libmaxminddb-dev \ libpcre2-dev \ libxml2-dev \ libfuzzy-dev \ pcre2-utils \ libpcre3-dev \ bison \ flex \ pkg-config - name: Run build preparation script run: ./build.sh - name: Configure env: CC: ${{ matrix.compiler.cc }} CXX: ${{ matrix.compiler.cxx }} run: ./configure ${{ matrix.platform.configure }} ${{ matrix.configure.opt }} --enable-assertions=yes - uses: ammaraskar/gcc-problem-matcher@master - name: Compile run: make -j "$(nproc)" - name: Run tests run: make check build-macos: name: macOS (${{ matrix.configure.label }}) runs-on: macos-15 strategy: fail-fast: false matrix: configure: - { label: "with parser generation", opt: "--enable-parser-generation" } - { label: "without curl", opt: "--without-curl" } - { label: "without lua", opt: "--without-lua" } - { label: "without maxmind", opt: "--without-maxmind" } - { label: "without libxml", opt: "--without-libxml" } - { label: "without geoip", opt: "--without-geoip" } - { label: "without ssdeep", opt: "--without-ssdeep" } - { label: "with lmdb", opt: "--with-lmdb" } - { label: "with pcre2 (default)", opt: "" } - { label: "with pcre", opt: "--with-pcre" } steps: - uses: actions/checkout@v6 with: fetch-depth: 0 submodules: recursive - name: Install dependencies # curl and pcre2 are typically already available in the macOS runner image run: | brew install autoconf \ automake \ libtool \ yajl \ lmdb \ lua \ libmaxminddb \ libxml2 \ ssdeep \ pcre \ bison \ flex - name: Run build preparation script run: ./build.sh - name: Configure run: ./configure ${{ matrix.configure.opt }} --enable-assertions=yes - uses: ammaraskar/gcc-problem-matcher@master - name: Compile run: make -j "$(sysctl -n hw.logicalcpu)" - name: Run tests run: make check build-windows: name: Windows (${{ matrix.platform.label }}, ${{ matrix.configure.label }}) runs-on: windows-2025 strategy: fail-fast: false matrix: platform: - { label: "x64", arch: "x86_64" } configuration: [Release] configure: - { label: "full", opt: "" } - { label: "without curl", opt: "-DWITH_CURL=OFF" } - { label: "without lua", opt: "-DWITH_LUA=OFF" } - { label: "without maxmind", opt: "-DWITH_MAXMIND=OFF" } - { label: "without libxml", opt: "-DWITH_LIBXML2=OFF" } - { label: "with lmdb", opt: "-DWITH_LMDB=ON" } steps: - uses: actions/checkout@v6 with: fetch-depth: 0 submodules: recursive - name: Install Conan package manager run: | pip3 install conan --upgrade conan profile detect - uses: ammaraskar/msvc-problem-matcher@master - name: Build project shell: cmd run: vcbuild.bat ${{ matrix.configuration }} ${{ matrix.platform.arch }} NO_ASAN "${{ matrix.configure.opt }}" - name: Prepare test environment working-directory: build\win32\build\${{ matrix.configuration }} env: BASE_DIR: ..\..\..\.. shell: cmd run: | copy unit_tests.exe %BASE_DIR%\test copy regression_tests.exe %BASE_DIR%\test copy libModSecurity.dll %BASE_DIR%\test copy %BASE_DIR%\unicode.mapping %BASE_DIR%\test md \tmp md \bin copy "C:\Program Files\Git\usr\bin\echo.exe" \bin copy "C:\Program Files\Git\usr\bin\echo.exe" \bin\echo - name: Disable unsupported tests on Windows working-directory: test\test-cases\regression shell: cmd run: | jq "map(if .title == \"Test match variable (1/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json jq "map(if .title == \"Test match variable (2/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json jq "map(if .title == \"Test match variable (3/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json jq "map(if .title == \"Variable offset - FILES_NAMES\" then .enabled = 0 else . end)" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json - name: Run tests working-directory: build\win32\build run: ctest -C ${{ matrix.configuration }} --output-on-failure cppcheck: name: Static analysis (cppcheck) runs-on: macos-15 steps: - uses: actions/checkout@v6 with: fetch-depth: 0 submodules: recursive - name: Install cppcheck run: | brew install autoconf automake libtool cppcheck libmaxminddb yajl lua lmdb ssdeep - name: Configure project run: | ./build.sh ./configure - name: Run cppcheck run: make check-static cppcheck-linux: name: Static analysis (cppcheck, Linux, debian:sid) runs-on: ubuntu-latest container: debian:sid steps: - name: Install basic tools run: | apt-get update apt-get install -y git - name: Mark repo as safe for git run: git config --global --add safe.directory $GITHUB_WORKSPACE - uses: actions/checkout@v6 with: fetch-depth: 0 submodules: recursive - name: Install dependencies (v2 style) run: | apt-get update apt-get install -y \ autoconf \ automake \ build-essential \ libtool \ pkg-config \ cppcheck \ libyajl-dev \ libcurl4-openssl-dev \ liblmdb-dev \ liblua5.2-dev \ libmaxminddb-dev \ libpcre2-dev \ libxml2-dev \ libfuzzy-dev \ pcre2-utils \ bison \ flex - name: Run build preparation script run: ./build.sh - name: Configure project run: ./configure - name: Run cppcheck run: make check-static ================================================ FILE: .gitignore ================================================ *.o *.lo *.la **/Makefile **/Makefile.in aclocal.m4 ar-lib autom4te.cache/ build/libtool.m4 build/ltoptions.m4 build/ltsugar.m4 build/ltversion.m4 build/lt~obsolete.m4 build/win32/build build/win32/CMakeUserPresets.json compile config.guess config.log config.status config.sub config.h.in~ configure configure~ depcomp modsecurity.pc .deps .libs .dirstamp src/config.h src/config.h.in src/location.hh src/position.hh src/stack.hh src/stamp-h1 src/headers.mk /test/rules_optimization /test/regression_tests /test/unit_tests /test-driver /test/massif.out.* /test/benchmark/benchmark /test/benchmark/owasp-v3/ /test/test-cases/regression/*.trs /test/test-cases/regression/*.log /test-suite.log ylwrap missing install-sh libtool ltmain.sh examples/simple_example_using_c/test /tools/rules-check/modsec-rules-check examples/multiprocess_c/multi examples/multithread/multithread examples/reading_logs_via_rule_message/simple_request examples/reading_logs_with_offset/read examples/using_bodies_in_chunks/simple_request ================================================ FILE: .gitmodules ================================================ [submodule "test/test-cases/secrules-language-tests"] path = test/test-cases/secrules-language-tests url = https://github.com/owasp-modsecurity/secrules-language-tests [submodule "others/libinjection"] path = others/libinjection url = https://github.com/libinjection/libinjection.git [submodule "bindings/python"] path = bindings/python url = https://github.com/owasp-modsecurity/ModSecurity-Python-bindings.git [submodule "others/mbedtls"] path = others/mbedtls url = https://github.com/Mbed-TLS/mbedtls.git ================================================ FILE: AUTHORS ================================================ zimmerle = Felipe Zimmerle rbarnett = Ryan C. Barnett csanders-git = Chaim Sanders victorhora = Victor Hora ================================================ FILE: CHANGES ================================================ v3.0.14 - 2025-Feb-25 --------------------- - [fix: fixed htmlEntityDecode methods] [PR from private repo - @theseion,@airween; fixed CVE-2025-27110] - fix: Added missing header to avoid build error with gcc-15 [PR #3342 - @airween] - Fix for issue #3334: build not finding YAJL [PR #3335 - @RooHTaylor] - fix: add value checking to @validateByteRange [PR #3322 - @airween] - fix: build library on OSX without GeoIP brew package [PR #3319 - @theseion,@airween] - Update README.md [PR #3314 - @ElevationsRPG] - Fix: Add false positive cppcheck-suppress for compatibility with upda… [PR #3307 - @gberkes] - fix: align TIME_MON variable's behavior [PR #3306 - @M4tteoP,@theseion,@airween] - Fix m_requestHostName variable behavior [PR #3298 - @airween] - Add regression rules for test [PR #3291 - @hnakamur] - Fix modsecurity-regression-test-secremoterules.txt URL in example [PR #3287 - @hnakamur] - Use latest version of cppcheck (2.15.0) to analyze codebase [PR #3283 - @eduar-hte] - Replace usage of range-checked 'at' method when vector/string has already been size checked [PR #3280 - @eduar-hte] - chore: add 'log' action to rule 200005 [PR #3266 - @airween] - docs: add a logo picture for github dark theme [PR #3264 - @xuruidong] - Leverage std::make_unique & std::make_shared to create objects in the heap [PR #3254 - @eduar-hte] - Simplified handling of RuleMessage by removing usage of std::shared_ptr [PR #3253 - @eduar-hte] - Simplified constructors, copy constructors & assignment operators [PR #3248 - @eduar-hte] v3.0.13 - 2024-Sep-03 --------------------- - Adjust reference to modsecurity::utils::string::VALID_HEX [PR #3243 - @eduar-hte] - Lua::run: Move logging of str parameter to higher log level. [PR #3240 - @frozenice] - Remove unnecessary heap allocated copies in Transformation actions [PR #3231 - @eduar-hte] - Removed multiple heap-allocated copies in Pm::init & parse_pm_content [PR #3233 - @eduar-hte] - Unit tests results should not be displayed in 'automake output' mode [PR #3232 - @eduar-hte] - Replace usage of std::ctime, which is not safe in multithread contexts [PR #3228 - @eduar-hte] - Removed unnecessary lock to call acmp_process_quick in Pm::evaluate [PR #3227 - @eduar-hte] - feat: Check if the MP header contains invalid character [PR #3225 - @airween] - Prevent concurrent access to data in InMemoryPerProcess' resolveXXX methods [PR #3216 - @eduar-hte] - Remove several string copies and unnecessary heap allocations [PR #3222 - @eduar-hte] - Creating a std::string with a null pointer is undefined behaviour [PR #3220 - @eduar-hte] - Simplifiy configuration to build using std C++17 [PR #3219 - @eduar-hte] - Remove unnecessary dynamic casts [PR #3218 - @eduar-hte] - fix: Sonarcloud reported memleak fixes [PR #3114 - @airween] - V3/sonarcloud replace this declaration by a structured binding declaration [PR #3217 - @gberkes] - Do not assume ModSecurityIntervention argument to transaction::intervention has been initialized/cleaned [PR #3212 - @eduar-hte] - Refactor: used the init-statement to declare "pos" inside the if statement [PR #3214 - @gberkes] - Refactor: moved 3 #include directives to the top of the file. [PR #3213 - @gberkes] - Fix SecRemoteRules regression test not to depend on a specific error message [PR #3211 - @eduar-hte] - Fixed shared files deadlock in a multi-threaded Windows application [PR #3210 - @eduar-hte] - Add cleanup methods to complete C based ABI [PR #3209 - @eduar-hte] - Build on macOS with Apple silicon (arm64) [PR #3208 - @eduar-hte] - remove 'this throw' call in transaction [PR #3207 - @gberkes] - New API function: set hostname for log [PR #3203 - @airween] - Fixing typo in Dockerfile [PR #3189 - @bitbehz] - Simplify checkout of submodules in GitHub workflows (with support for git describe) [PR #3185 - @eduar-hte] - Update README.md: use submodule and use benchmark tool [PR #3182 - @airween] - Improve performance of VariableOrigin instances [PR #3164 - @eduar-hte] - Update libinjection & Mbed TLS [PR #3161 - @eduar-hte] - chore: add PR template (v3) [PR #3160 - @fzipi] - Update to seclang-scanner changes introduced by Windows support [PR #3146 - @eduar-hte] - GitHub build & quality assurance workflow updates [PR #3144 - @eduar-hte] - Add link to Rust bindings in README [PR #3141 - @rkrishn7] - Remove cppcheck suppressions with line numbers in test/cppcheck_suppressions.txt [PR #3134 - @eduar-hte] - Add support to build libModSecurity v3 on Windows [PR #3132 - @eduar-hte] - fix: update submodule url [PR #3128 - @fzipi] - fix(rbl): typo in rbl check selector [PR #3127 - @fzipi] - fix: Changed 'equal_range()' + loop by 'find()' in resolveFirst() methods [PR #3117 - @airween] - Deleted redundant code in 'ModSecurity::serverLog(...)'. [PR #3116 - @gberkes] - doc: Update CHANGES [PR #3101 - @airween] - Reduce the scope of variables in a for loop [PR #3098 - @devzero2000] - Clean up 'return' never will be executed. [PR #3096 - @gberkes] - fix: Replace obsolete macros [PR #3095 - @airween] - fix: Change 'SecEngineStatus' to Off by default [PR #3092 - @airween] - chore: update bug-report-for-version-3-x.md [PR #3086 - @fzipi] - test: Logical, syntax and cosmetic fixes on test cases [PR #3080 - @MirkoDziadzka, @airween] - Bump the C++ version from C++11 to C++17 [PR #3079 - @MirkoDziadzka] - fix: makes uri decode platform independent [PR #3016 - @M4tteoP] v3.0.12 - 2024-Jan-30 --------------------- - Change REQUEST_FILENAME and REQUEST_BASENAME behavior [Issue #3048 - @martinhsv, @theMiddleBlue, @theseion, @M4tteoP, @airween] - Set the minimum security protocol version for SecRemoteRules [Issue security/code-scanning/2 - @airween] v3.0.11 - 2023-Dec-06 --------------------- - Add WRDE_NOCMD to wordexp call [Issue #3024 - @sahruldotid, @martinhsv] - Fix: validateDTD compile fails if when libxml2 not installed [Issue #3014 - @zangobot, @martinhsv] - Fix memory leak of validateDTD's dtd object [Issue #3008 - @martinhsv, @zimmerle] - Fix memory leaks in ValidateSchema [Issue #3005 - @martinhsv, @zimmerle] - Add support for expirevar action [Issue #1803, #3001 - @martinhsv] - Fix: lmdb regex match on non-null terminated string [Issue #2985 - @martinhsv] - Fix memory leaks in lmdb code (new'd strings) [Issue #2983 - @martinhsv] - Configure: add additional name to pcre2 pkg-config list [Issue #2939 - @agebhar1, @fzipi, @martinhsv] v3.0.10 - 2023-Jul-25 --------------------- - Fix: worst-case time in implementation of four transformations [Issue #2934 - @martinhsv] - Add TX synonym for MSC_PCRE_LIMITS_EXCEEDED [Issue #2901 - @airween] - Make MULTIPART_PART_HEADERS accessible to lua [Issue #2916 - @martinhsv] - Fix: Lua scripts cannot read whole collection at once [Issue #2900 - @udi-aharon, @airween, @martinhsv] - Fix: quoted Include config with wildcard [Issue #2905 - @wiseelf, @airween, @martinhsv] - Support isolated PCRE match limits [Issue #2736 - @brandonpayton, @martinhsv] - Fix: meta actions not applied if multiMatch in first rule of chain [Issue #2867, #2868 - @mlevogiannis, @martinhsv] - Fix: audit log may omit tags when multiMatch [Issue #2866 - @mlevogiannis] - Exclude CRLF from MULTIPART_PART_HEADER value [Issue #2870 - @airween, @martinhsv] - Configure: use AS_ECHO_N instead echo -n [Issue #2894 - @liudongmiao, @martinhsv] - Adjust position of memset from 2890 [Issue #2891 - @mirkodziadzka-avi, @martinhsv] - Add test: empty lines in ipMatchFromFile test [Issue #2846 - @tomsommer] v3.0.9 - 2023-Apr-12 -------------------- - Fix: possible segfault on reload if duplicate ip+CIDR in ip match list [Issue #2877, #2890 - @tomsommer, @martinhsv] - Add some member variable inits in Transaction class (possible segfault) [Issue #2886 - @GNU-Plus-Windows-User, @airween, @mdounin, @martinhsv] - Resolve memory leak on reload (bison-generated variable) [Issue #2876 - @martinhsv] - Support equals sign in XPath expressions [Issue #2328 - @dennus, @martinhsv] - Encode two special chars in error.log output [Issue #2854 - @airween, @martinhsv] - Add JIT support for PCRE2 [Issue #2791 - @wfjsw, @airween, @FireBurn, @martinhsv] - Support comments in ipMatchFromFile file via '#' token [Issue #2554 - @tomsommer, @martinhsv] - Use name package name libmaxminddb with pkg-config [Issue #2595, #2596 - @frankvanbever, @ffontaine, @arnout] - Fix: FILES_TMP_CONTENT collection key should use part name [Issue #2831 - @airween] - Use AS_HELP_STRING instead of obsolete AC_HELP_STRING macro [Issue #2806 - @hughmcmaster] - During configure, do not check for pcre if pcre2 specified [Issue #2750 - @dvershinin, @martinhsv] - Use pkg-config to find libxml2 first [Issue #2714 - @hughmcmaster] - Fix two rule-reload memory leak issues [Issue #2801 - @Abce, @martinhsv] - Correct whitespace handling for Include directive [Issue #2800 - @877509395, @martinhsv] v3.0.8 - 2022-Sep-07 -------------------- - Adjust parser activation rules in modsecurity.conf-recommended [Issue #2796 - @terjanq, @martinhsv] - Multipart parsing fixes and new MULTIPART_PART_HEADERS collection [Issue #2795 - @terjanq, @martinhsv] - Prevent LMDB related segfault [Issue #2755, #2761 - @dvershinin] - Fix msc_transaction_cleanup function comment typo [Issue #2788 - @lookat23] - Fix: MULTIPART_INVALID_PART connected to wrong internal variable [Issue #2785 - @martinhsv] - Restore Unique_id to include random portion after timestamp [Issue #2752, #2758 - @datkps11, @martinhsv] v3.0.7 - 2022-May-30 -------------------- - Move PCRE2 match block from member variable [@martinhsv] - Add SecArgumentsLimit, 200007 to modsecurity.conf-recommended [Issue #2738 - @jleproust, @martinhsv] - Fix memory leak when concurrent log includes REMOTE_USER [Issue #2727 - @liudongmiao] - Fix LMDB initialization issues [Issue #2688 - @ziollek, @martinhsv] - Fix initcol error message wording [Issue #2732 - @877509395, @martinhsv] - Tolerate other parameters after boundary in multipart C-T [Issue #1900 - @martinhsv] - Add DebugLog message for bad pattern in rx operator [Issue #2723 - @martinhsv] - Support PCRE2 [Issue #2668 - @martinhsv] - Support SecRequestBodyNoFilesLimit [Issue #2670 - @airween, @martinhsv] - Fix misuses of LMDB API [Issue #2601, #2602 - @hyc] - Fix duplication typo in code comment [Issue #2677 - @gleydsonsoares] - Add ctl:auditEngine action support [Issue #2606 - @alekravch, @martinhsv] - Fix multiMatch msg, etc, population in audit log [Issue #2573 - @Sachin-M-Desai, @martinhsv] - Fix some name handling for ARGS_*NAMES: regex SecRuleUpdateTargetById, etc. [Issue #2627, #2648 - @lontchianicet, @victorserbu2709, @martinhsv] - Adjust confusing variable name in setRequestBody method [Issue #2635 - @Mesar-Ali, @martinhsv] - Multipart names/filenames may include single quote if double-quote enclosed [Issue #2352 - @martinhsv] - Add SecRequestBodyJsonDepthLimit to modsecurity.conf-recommended [Issue #2647 - @theMiddleBlue, @airween, @877509395 ,@martinhsv] v3.0.6 - 2021-Nov-19 -------------------- - Support configurable limit on depth of JSON parsing [@theMiddleBlue, @martinhsv] v3.0.5 - 2021-Jul-07 -------------------- - Handle URI received with uri-fragment [@martinhsv] - Having ARGS_NAMES, variables proxied [@zimmerle, @martinhsv, @KaNikita] - Use explicit path for cross-compile environments. [Issue #2485 - @dtoubelis] - Fix: FILES variable does not use multipart part name for key [Issue #2377 - @martinhsv] - Replaces put with setenv in SetEnv action [Issue #2469 - @martinhsv, @WGH-, @zimmerle] - Regression: Mark the test as failed in case of segfault. [@zimmerle] - Regex key selection should not be case-sensitive [Issue #2296, #2107, #2297 - @michaelgranzow-avi, @victorhora, @airween, @martinhsv, @zimmerle] - Fix: Only delete Multipart tmp files after rules have run [Issue #2427 - @martinhsv] - Fixed MatchedVar on chained rules [Issue #2423, #2435, #2436 - @michaelgranzow-avi] - Add support for new operator rxGlobal [@martinhsv] - Fix maxminddb link on FreeBSD [Issue #2131 - @granalberto, @zimmerle] - Fix IP address logging in Section A [Issue #2300 - @inaratech, @zavazingo, @martinhsv] - Adds support to lua 5.4 [@zimmerle] - GeoIP: switch to GEOIP_MEMORY_CACHE from GEOIP_INDEX_CACHE [Issues #2378, #2186 - @defanator] - rx: exit after full match (remove /g emulation); ensure capture groups occuring after unused groups still populate TX vars [Issue #2336 - @martinhsv] - Correct CHANGES file entry for #2234 - Add support to test framework for audit log content verification and add regression tests for issues #2000, #2196 - Support configurable limit on number of arguments processed [Issue #2234 - @jleproust, @martinhsv] - Multipart Content-Dispostion should allow field: filename*= [@martinhsv] - Fix rule-update-target for non-regex [Issue 2251 - @martinhsv] - Fix configure script when packaging for Buildroot [Issue 2235 - @frankvanbever] - modsecurity.pc.in: add Libs.private [Issue #1918, #2253 - @ffontaine, @Dridi, @victorhora] v3.0.4 - 2020-Jan-13 -------------------- - Fix: audit log data omitted when nolog,auditlog [@martinhsv] - Fix: ModSecurity 3.x inspectFile operator does not pass FILES_TMPNAMES parameter to lua engine [Issue #2204, #2205 - @kadirerdogan] - XML: Remove error messages from stderr [Issue #2010 - @JaiHarpalani, @zimmerle] - Filter comment or blank line for pmFromFile operator [Issue #1645 - @LeeShan87, @victorhora, @tdoubley] - Additional adjustment to Cookie header parsing [@martinhsv] - Restore chained rule part H logging to be more like 2.9 behaviour [Issue #2196 - @martinhsv] - Small fixes in log messages to help debugging the file upload [Issue #2130 - @airween] - Fix Cookie header parsing issues [Issue #2201 - @airween, @martinhsv] - Fix rules with nolog are logging to part H [Issue #2196 - @martinhsv] - Fix argument key-value pair parsing cases [Issue #1904 - @martinhsv] - Fix: audit log part for response body for JSON format to be E [Issue #2066 - @martinhsv, @zimmerle] - Make sure m_rulesMessages is filled after successfull match [Issue #2000, #2048 - @victorhora, @defanator] - Fix @pm lookup for possible matches on offset zero. [@zimmerle, @afoxdavidi, @martinhsv, @marshal09] - Regex lookup on the key name instead of COLLECTION:key [@rdiperri-yottaa, @danbiagini-work, @mmelo-yottaa, @zimmerle] - Missing throw in Operator::instantiate [Issue #2106 - @marduone] - Making block action execution dependent of the SecEngine status [Issue #2113, #2111 - @theMiddleBlue, @airween] - Making block action execution dependent of the SecEngine status [Issue #1960 - @theMiddleBlue, @zimmerle, @airween, @victorhora] - Having body limits to respect the rule engine state [@zimmerle] - Fix SecRuleUpdateTargetById does not match regular expressions [Issue #1872 - @zimmerle, @anush-cr, @victorhora, @j0k2r] - Adds missing check for runtime ctl:ruleRemoveByTag [Issue #2102, #2099 - @airween] - Adds a new operator verifySVNR that checks for Austrian social security numbers. [Issue #2063 - @Rufus125] - Fix variables output in debug logs [Issue #2057 - @jleproust] - Correct typo validade in log output [Issue #2059 - @nerrehmit] - fix/minor: Error encoding hexa decimal. [Issue #2068 - @tech-ozon-io] - Limit more log variables to 200 characters. [Issue #2073 - @jleproust] - parser: fix parsed file names [@zimmerle] - Allow empty anchored variable [Issue #2024 - @airween] - Fixed FILES_NAMES collection after the end of multipart parsing [Issue #2016 - @airween] - Fixed validateByteRange parsing method [Issue #2017 - @airween] - Removes a memory leak on the JSON parser [@zimmerle] - Enables LMDB on the regression tests. [Issue #2011, #2008 - @WGH-, @mdunc] - Fix: Extra whitespace in some configuration directives causing error [Issue #2006 - @porjo, @zimmerle] - Refactoring on Regex and SMatch classes. [@WGH-] - Fixed buffer overflow in Utils::Md5::hexdigest() [Issue #2002 - @defanator] - Implemented merge() method for ConfigInt, ConfigDouble, ConfigString [Issue #1990 - @defanator] - Adds initially support to the drop action. [@zimmerle] - Complete merging of particular rule properties [Issue #1978 - @defanator] - Replaces AC_CHECK_FILE with 'test -f' [Issue #1984 - @chuckwolber] - Fix inet addr handling on 64 bit big endian systems [Issue #1980 - @airween] - Fix tests on FreeBSD [Issue #1973 - @defanator] - Changes ENV test case to read the default MODSECURTIY env var [Issue #1969 - @zimmerle, @airween, @inittab] - Regression: Sets MODSECURITY env var during the tests execution [Issue #1969 - @zimmerle, @airween, @inittab] - Fix setenv action to strdup key=variable [@zimmerle] - Allow 0 length JSON requests. [Issue #1822 - @allanbomsft, @zimmerle, @victorhora, @marcstern] - Fix "make dist" target to include default configuration [Issue #1966 - @defanator] - Replaced log locking using mutex with fcntl lock [Issue #1949, #1927 - @Cloaked9000] - Correct the usage of modsecurity::Phases::NUMBER_OF_PHASES [Issue #1959 - @weliu] - Adds support to multiple ranges in ctl:ruleRemoveById [Issue #1956 - @theseion, @victorhora, @zimmerle] - Rule variable interpolation broken [Issue #1961 - @soonum, @zimmerle] - Make the boundary check less strict as per RFC2046 [Issue #1943 - @victorhora, @allanbomsft] - Fix buffer size for utf8toUnicode transformation [Issue #1208 - @katef, @victorhora] v3.0.3 - 2018-Nov-05 -------------------- - Fix double macros bug [Issue #1943 - @supplient, @zimmerle] - Override the default status code if not suitable to redirect action [Issue #1850 - @zimmerle, @victorhora] - parser: Fix the support for CRLF configuration files [Issue #1945 - @zimmerle, @defanator, @kjakub] - Organizes the server logs [0xb7c36 and 0x5ac20 - @zimmerle, @steven-j-wojcik] - m_lineNumber in Rule not mapping with the correct line number in file [Issue #1844 - @zimmerle, @victorhora, @xizeng] - Using shared_ptr instead of unique_ptr on rules exceptions [Issue #1697 - @zimmerle, @brianp9906, @victorhora, @LeSwiss, @defanator] - Changes debuglogs schema to avoid unecessary str allocation [0xb2840 - @zimmerle] - Fix the SecUnicodeMapFile and SecUnicodeCodePage [0x3094d - @zimmerle, @victorhora] - Changes the timing to save the rule message [0xca270 - @zimmerle] - Fix crash in msc_rules_add_file() when using disruptive action in chain [Issue #1849 - @victorhora, @zimmerle, @rperper] - Fix memory leak in AuditLog::init() [Issue #1897 - @weliu] - Fix RulesProperties::appendRules() [Issue #1901 - @steven-j-wojcik] - Fix RULE lookup in chained rules [0x3077c - @zimmerle] - @ipMatch "Could not add entry" on slash/32 notation in 2.9.0 [Issue #849 - @zimmerle, @dune73] - Using values after transformation at MATCHED_VARS [0x14316 - @zimmerle] - Adds support to UpdateActionById. [Issue #1800 - @zimmerle, @victorhora, @NisariAIT] - Add correct C function prototypes for msc_init and msc_create_rule_set [Issue #1922 - @steven-j-wojcik] - Allow LuaJIT 2.1 to be used [Issue #1909 - @victorhora, @mdunc] - Match m_id JSON log with RuleMessage and v2 format [Issue #1185 - @victorhora] - Adds support to setenv action. [Issue #1044 - @zimmerle] - Adds new transaction constructor that accepts the transaction id as parameter. [Issue #1627 - @defanator, @zimmerle] - Adds request IDs and URIs to the debug log [Issue #1627 - @defanator, @zimmerle] - Treating variables exception on load-time instead of run time. [0x028e0 and 0x275a1 - @zimmerle] - Fix: function m.setvar in Lua scripts and add testcases [Issue #1859 - @nowaits, @victorhora] - Fix SecResponseBodyAccess and ctl:requestBodyAccess directives [Issue #1531 - @victorhora, @defanator] - Fix OpenBSD build [Issue #1841 - @victorhora, @zimmerle, @juanfra684] - Fix parser to support GeoLookup with MaxMind [Issue #1884, #1895 - @victorhora, @everping] - parser: Fix simple quote setvar in the end of the line [Issue #1831 - @zimmerle, @csanders-git] - Fix pc file [Issue #1847 - @gquintard] - modsec_rules_check: uses the gnu `.la' instead of `.a' file [Issue #1853 - @ste7677, @victorhora, @zimmerle] - good practices: Initialize variables before use it [Issue #1889 - Marc Stern] - Fix utf-8 character encoding conversion [Issue #1794 - @tinselcity, @zimmerle] - Adds support for ctl:requestBodyProcessor=URLENCODED [Issue #1797 - @victorhora] - Add LUA compatibility for CentOS and try to use LuaJIT first if available [Issue #1622 - @victorhora, @dmitryzykov] - Allow LuaJIT to be used [Issue #1809 - @victorhora, @p0pr0ck5] - Implement support for Lua 5.1 [Issue #1809 - @p0pr0ck5, @victorhora] - Variable names must match fully, not partially. Match should be case insensitive. [Issue #1818, #1820, #1810, #1808 - @michaelgranzow-avi, @victorhora, @theMiddleBlue, @airween, @zimmerle, @LeeShan87] - Improves the performance while loading the rules [Issue #1735 - @zimmerle, @p0pr0ck5, @victorhora] - Allow empty strings to be evaluated by regex::searchAll [Issue #1799, #1785 - @victorhora, @XuanHuyDuong, @zimmerle] - Adds basic pkg-config info [Issue #1790 - @gquintard, @zimmerle] - Fixed LMDB collection errors [Issue #1787 - @airween, @zimmerle] - Fixed false positive MULTIPART_UNMATCHED_BOUNDARY errors [Issue #1747, #1924 - @airween, @victorhora, @defanator, @zimmerle] - Fix ip tree lookup on netmask content [Issue #1793 - @tinselcity, @zimmerle] - Changes the behavior of the default sec actions [Issue #1629 - @mirkodziadzka-avi, @zimmerle, @victorhora] - Refactoring on {global,ip,resources,session,tx,user} collections [Issue #1754, #1778 - @LeeShan87, @zimmerle, @victorhora, @wwd5613, @sobigboy] - Fix race condition in UniqueId::uniqueId() [Issue #1786 - @weliu] - Fix memory leak in error message for msc_rules_merge C APIs [Issue #1765 - @weliu] - Return false in SharedFiles::open() when an error happens [Issue #1783 - @weliu] - Use rvalue reference in ModSecurity::serverLog [Issue #1769 - @weliu] - Build System: Fix when multiple lines for curl version. [Issue #1771 - @Artistan] - Checks if response body inspection is enabled before process it [Issue #1643 - @zoltan-fedor, @dennus, @defanator, @zimmerle] - Code Cleanup. [Issue #1757, #1755, #1756, #1761 - @p0pr0ck5] - Fix setvar parsing of quoted data [Issue #1733, #1759, #1775 - @victorhora, @JaiHarpalani, @defanator] - Fix LDFLAGS for unit tests. [Issue #1758 - @smlx] - Adds time stamp back to the audit logs [Issue #1762 - @Pjack, @zimmerle] - Disables skip counter if debug log is disabled [@zimmerle] - Cosmetics: Represents amount of skipped rules without decimal [Issue #1737 - @p0pr0ck5] - Add missing escapeSeqDecode, urlEncode and trimLeft/Right tfns to parser [Issue #1752 - @victorhora] - Fix STATUS var parsing and accept STATUS_LINE var for v2 backward comp. [Issue #1738 - @victorhora] - Fix memory leak in modsecurity::utils::expandEnv() [Issue #1750 - @defanator] - Initialize m_dtd member in ValidateDTD class as NULL [Issue #1751 - @airween] - Fix broken @detectxss operator regression test case [Issue #1739 - @p0pr0ck5] - Fix utils::string::ssplit() to handle delimiter in the end of string [Issue #1743, #1744 - @defanator] - Fix variable FILES_TMPNAMES [Issue #1646, #1610 - @victorhora, @zimmerle, @defanator] - Fix memory leak in Collections [Issue #1729, #1730 - @defanator] v3.0.2 - 2018-Apr-03 -------------------- - Fix lib version information while generating the .so file [@gl1f1v21, @zimmerle] v3.0.1 - 2018-Apr-02 -------------------- - Adds support for ctl:ruleRemoveByTag [@zimmerle, @weliu] - Fix SecUploadDir configuration merge [Issue #1720 - @zimmerle, @gjvanetten] - Include all prerequisites for "make check" into dist archive [Issue #1716 - @defanator] - Fix: Reverse logic of checking output in @inspectFile [Issue #1715 - @defanator] - Adds support to libMaxMind [Issue #1307 - @zimmerle, @defanator] - Adds capture action to detectXSS [Issue #1698 - @victorhora] - Temporarily accept invalid MULTIPART_SEMICOLON_MISSING operator [Issue #1701 - @victorhora] - Adds capture action to detectSQLi [Issue #1698 - @zimmerle] - Adds capture action to rbl [Issue #1698 - @zimmerle] - Adds capture action to verifyCC [Issue #1698 - @michaelgranzow-avi, @zimmerle] - Adds capture action to verifySSN [Issue #1698 - @zimmerle] - Adds capture action to verifyCPF [Issue #1698 - @zimmerle] - Prettier error messages for unsupported configurations (UX) [@victorhora] - Add missing verify*** transformation statements to parser [Issue #1006 and #1007 - @victorhora] - Fix a set of compilation warnings [Issue #1650 - @zimmerle, @JayCase] - Check for disruptive action on SecDefaultAction. [Issue #1614 - @zimmerle, @michaelgranzow-avi] - Fix block-block infinite loop. [Issue #1614 - @zimmerle, @michaelgranzow-avi] - Correction remove_by_tag and remove_by_msg logic. [Issue #1636 - @Minasu] - Fix LMDB compile error [Issue #1691 - @airween] - Fix msc_who_am_i() to return pointer to a valid C string [Issue #1640 - @defanator] - Added some cosmetics to autoconf related code [Issue #1652 - @airween] - Fix "make dist" target to include necessary headers for Lua [Issue #1678 - @defanator] - Fix "include /foo/*.conf" for single matched object in directory [Issue #1677 - @defanator, @zimmerle] - Add missing Base64 transformation statements to parser [Issue #1632 - @victorhora, @zimmerle] - Fixed resource load on ip match from file [#1674 - @zimmerle, @StefaanSeys] - Fixed examples compilation while using disable-shared [#1670 - @zimmerle, @ivanbaldo] - Fixed compilation issue while xml is disabled [0x243028 - @zimmerle] - Having LDADD and LDFLAGS organized on Makefile.am [0xd0e85e - @zimmerle] - Checking std::deque size before use it [0x217cbf - @zimmerle, Yaron Dayagi] - perf improvement: Added the concept of RunTimeString and removed all run time parser. [0x3eae51 0x0320e0 0xb5688f 0xfe47a9 0xfa9842 0x1affc3 0x079de4 0xc7c04f 0x5262ea 0x01974a 0xd5ee1e - @zimmerle] - perf improvement: Checks debuglog level before format debug msg [0x42ee9 - @zimmerle] - perf. improvement/rx: Only compute dynamic regex in case of macro [0x91ff3 - @zimmerle] - Fix uri on the benchmark utility [0x63bec - @zimmerle] - disable Lua on systems with liblua5.1 [Issue #1639 - @victorhora, @defanator] v3.0.0 - 2017-Dec-13 -------------------- - Improvements on LUA build scripts and support for LUA 5.2. [Issue #1617 and #1622 - @victorhora, @zimmerle] - Fix compilation error with disable_debug_log flag [0xfd84e - Izik Abramov] - Improvements on the benchmark tool. [Issue #1615 - @zimmerle] - Fix lua headers on the build scripts [Issue #1621 - @Minasu] - Refactoring on the JSON parser. [Issue #1576, #1577 - Tobias Gutknecht, @zimmerle, @victorhora, @marcstern] - Adds support to WEBAPPID variable. [Issue #1027 - @zimmerle, @victorhora] - Adds support for SecWebAppId. [Issue #1442 - @zimmerle, @victorhora] - Adds support for SecRuleRemoveByTag. [Issue #1476 - @zimmerle, @victorhora] - Adds support for update target by message. [Issue #1474 - @zimmerle, @victorhora] - Adds support to SecRuleScript directive. [Issue #994 - @zimmerle] - Adds support for the exec action. [Issue #1050 - @zimmerle] - Adds support for transformations inside Lua engine [Issue #994 - @zimmerle] - Adds initial support for Lua engine. [Issue #994 - @zimmerle] - Adds support for @inspectFile operator. [Issue #999 - @zimmerle, @victorhora] - Adds support for RESOURCE variable collection. [Issue #1014 - @zimmerle, @victorhora] - Adds support for @fuzzyHash operator. [Issue #997 - @zimmerle] - Fix build on non x86 arch build [Issue #1598 - @athmane] - Fix memory issue while changing rule target dynamic [Issue #1590 - @zimmerle, @slabber] - Fix log while displaying the name of a dict selection by regex. [@zimmerle] - Setting http response code on the auditlog. [Issue #1592 - @zimmerle] - Refactoring on RuleMessage class, now accepting http code as parameter. [@zimmerle] - Having disruptive msgs as disruptive [instead of warnings] on audit log [Issue #1592 - @zimmerle, @nobodysz] - Parser: Pipes are no longer welcomed inside regex dict element selection. [Issue #1591 - @zimmerle, @slabber] - Avoids unicode initialization on every rules object [Issue #1563 - @zimmerle, @Tiki-God, @sethinsd, @Cloaked9000, @AnoopAlias, @intelbg] - Makes clear to the user whenever the audit log is empty due to missing JSON support. [Issue #1585 - @zimmerle] - Makes auditlog more verbose on debug logs [Issue: #1559 - @zimmerle] - Enable support for AuditLogFormat Issue: #1583, #1493 and #1453 - @victorhora] - Adds macro expansion for @rx operator [Issue: #1528, #1536 - @asterite3, @zimmerle] - Consideres under quoted variable while loading the rules. [Felipe Zimmerle/@zimmerle, Victor Hora/@victorhora] - Store the connection and url parameters in std::string [Issue: #1571 - @majordaw] - Eliminate some reorder and sign warnings [Issue: #1572 - Dávid Major/@majordaw] - Makes parallel logging to work when SELinux is enabled. [Issue: #1562 - David Buckle/@met3or] - Adds possibility to run the pm operator inside a mutex to avoid concurrent access while working on a thread environment. This option is a compilation flag. [Felipe Zimmerle/@zimmerle] v3.0.0-rc1 - 2017-Aug-28 ------------------------ Very first public version. ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: Makefile.am ================================================ if TEST_UTILITIES export MAYBE_TEST = test endif if EXAMPLES export MAYBE_EXAMPLES = examples endif SUBDIRS = \ others \ src \ doc \ tools \ $(MAYBE_EXAMPLES) \ $(MAYBE_TEST) # make clean CLEANFILES = ACLOCAL_AMFLAGS = -I build # make maintainer-clean MAINTAINERCLEANFILES = \ aclocal.m4 \ ar-lib \ build/libtool.m4 \ build/lt~obsolete.m4 \ build/ltoptions.m4 \ build/ltsugar.m4 \ build/ltversion.m4 \ coding-style.txt \ compile \ config.guess \ config.sub \ configure \ cppcheck.txt \ depcomp \ install-sh \ ltmain.sh \ Makefile.in \ missing \ test/modsec-shared-collections \ test/modsec-shared-collections-lock \ test-suite-drd.log \ test-suite-helgrind.log \ test-suite-memcheck.log \ ylwrap parser: cat src/parser/seclang-parser.hh | sed "s/return \*new (yyas_ ()) T (t)/return *new (yyas_ ()) T (std::move((T\&)t))/g" > src/parser/seclang-parser.hh.fix && mv src/parser/seclang-parser.hh.fix src/parser/seclang-parser.hh cppcheck: @cppcheck -U YYSTYPE -U MBEDTLS_MD5_ALT -U MBEDTLS_SHA1_ALT \ -D MS_CPPCHECK_DISABLED_FOR_PARSER -U YY_USER_INIT \ --suppressions-list=./test/cppcheck_suppressions.txt \ --inline-suppr \ --enable=warning,style,performance,portability,unusedFunction,missingInclude \ --inconclusive \ --template="warning: {file},{line},{severity},{id},{message}" \ -I headers -I . -I $(top_srcdir)/others -I $(top_srcdir)/src -I $(top_srcdir)/others/mbedtls/include \ --error-exitcode=1 \ -i "src/parser/seclang-parser.cc" -i "src/parser/seclang-scanner.cc" \ -i others \ --std=c++17 \ --force --verbose . check-static: cppcheck check-style: check-coding-style check-coding-style: @cpplint.py \ $$(find . -name "*.h" -o -name "*.cc" | xargs) 2>&1 \ | egrep -v $$(echo -n "catchall" ; \ for i in $$(cat test/coding_style_suppressions.txt); do echo -n "|"$$i; done) \ | sed 's/^\./warning: ./g' > coding-style.txt -cat coding-style.txt @VALGRIND_CHECK_RULES@ VALGRIND_SUPPRESSIONS_FILES = valgrind_suppressions.txt LOG_DRIVER = env $(SHELL) $(top_srcdir)/test/custom-test-driver AM_TESTS_ENVIRONMENT=AUTOMAKE_TESTS=true; export AUTOMAKE_TESTS; LOG_COMPILER=test/test-suite.sh TESTS= include test/test-suite.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = modsecurity.pc EXTRA_DIST = modsecurity.pc.in \ modsecurity.conf-recommended \ unicode.mapping ================================================ FILE: README.md ================================================ ![Quality Assurance](https://github.com/owasp-modsecurity/ModSecurity/workflows/Quality%20Assurance/badge.svg) [![Build Status](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=alert_status)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) [![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=sqale_rating )](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) [![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=reliability_rating )](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) [![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=security_rating )](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) [![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=vulnerabilities )](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity) Libmodsecurity is one component of the ModSecurity v3 project. The library codebase serves as an interface to ModSecurity Connectors taking in web traffic and applying traditional ModSecurity processing. In general, it provides the capability to load/interpret rules written in the ModSecurity SecRules format and apply them to HTTP content provided by your application via Connectors. If you are looking for ModSecurity for Apache (aka ModSecurity v2.x), it is still under maintenance and available: [here](https://github.com/owasp-modsecurity/ModSecurity/tree/v2/master). ### What is the difference between this project and the old ModSecurity (v2.x.x)? * All Apache dependencies have been removed * Higher performance * New features * New architecture Libmodsecurity is a complete rewrite of the ModSecurity platform. When it was first devised the ModSecurity project started as just an Apache module. Over time the project has been extended, due to popular demand, to support other platforms including (but not limited to) Nginx and IIS. In order to provide for the growing demand for additional platform support, it has became necessary to remove the Apache dependencies underlying this project, making it more platform independent. As a result of this goal we have rearchitected Libmodsecurity such that it is no longer dependent on the Apache web server (both at compilation and during runtime). One side effect of this is that across all platforms users can expect increased performance. Additionally, we have taken this opportunity to lay the groundwork for some new features that users have been long seeking. For example we are looking to natively support auditlogs in the JSON format, along with a host of other functionality in future versions. ### It is no longer just a module. The 'ModSecurity' branch no longer contains the traditional module logic (for Nginx, Apache, and IIS) that has traditionally been packaged all together. Instead, this branch only contains the library portion (libmodsecurity) for this project. This library is consumed by what we have termed 'Connectors' these connectors will interface with your webserver and provide the library with a common format that it understands. Each of these connectors is maintained as a separate GitHub project. For instance, the Nginx connector is supplied by the ModSecurity-nginx project (https://github.com/owasp-modsecurity/ModSecurity-nginx). Keeping these connectors separated allows each project to have different release cycles, issues and development trees. Additionally, it means that when you install ModSecurity v3 you only get exactly what you need, no extras you won't be using. # Compilation Before starting the compilation process, make sure that you have all the dependencies in place. Read the subsection “Dependencies” for further information. After the compilation make sure that there are no issues on your build/platform. We strongly recommend the utilization of the unit tests and regression tests. These test utilities are located under the subfolder ‘tests’. As a dynamic library, don’t forget that libmodsecurity must be installed to a location (folder) where you OS will be looking for dynamic libraries. ### Unix (Linux, MacOS, FreeBSD, …) On unix the project uses autotools to help the compilation process. Please note that if you are working with `git`, don't forget to initialize and update the submodules. Here's a quick how-to: ```shell $ git clone --recursive https://github.com/owasp-modsecurity/ModSecurity ModSecurity $ cd ModSecurity ``` You can then start the build process: ```shell $ ./build.sh $ ./configure $ make $ sudo make install ``` Details on distribution specific builds can be found in our Wiki: [Compilation Recipes](https://github.com/owasp-modsecurity/ModSecurity/wiki/Compilation-recipes) ### Windows Windows build information can be found [here](build/win32/README.md). ## Dependencies This library is written in C++ using the C++17 standards. It also uses Flex and Yacc to produce the “Sec Rules Language” parser. Other, mandatory dependencies include YAJL, as ModSecurity uses JSON for producing logs and its testing framework, libpcre (not yet mandatory) for processing regular expressions in SecRules, and libXML2 (not yet mandatory) which is used for parsing XML requests. All others dependencies are related to operators specified within SecRules or configuration directives and may not be required for compilation. A short list of such dependencies is as follows: * libinjection is needed for the operator @detectXSS and @detectSQL * curl is needed for the directive SecRemoteRules. If those libraries are missing ModSecurity will be compiled without the support for the operator @detectXSS and the configuration directive SecRemoteRules. # Library documentation The library documentation is written within the code in Doxygen format. To generate this documentation, please use the doxygen utility with the provided configuration file, “doxygen.cfg”, located with the "doc/" subfolder. This will generate HTML formatted documentation including usage examples. # Library utilization The library provides a C++ and C interface. Some resources are currently only available via the C++ interface, for instance, the capability to create custom logging mechanism (see the regression test to check for how those logging mechanism works). The objective is to have both APIs (C, C++) providing the same functionality, if you find an aspect of the API that is missing via a particular interface, please open an issue. Inside the subfolder examples, there are simple examples on how to use the API. Below some are illustrated: ### Simple example using C++ ```c++ using ModSecurity::ModSecurity; using ModSecurity::Rules; using ModSecurity::Transaction; ModSecurity *modsec; ModSecurity::Rules *rules; modsec = new ModSecurity(); rules = new Rules(); rules->loadFromUri(rules_file); Transaction *modsecTransaction = new Transaction(modsec, rules); modsecTransaction->processConnection("127.0.0.1"); if (modsecTransaction->intervention()) { std::cout << "There is an intervention" << std::endl; } ``` ### Simple example using C ```c #include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" char main_rule_uri[] = "basic_rules.conf"; int main (int argc, char **argv) { ModSecurity *modsec = NULL; Transaction *transaction = NULL; Rules *rules = NULL; modsec = msc_init(); rules = msc_create_rules_set(); msc_rules_add_file(rules, main_rule_uri); transaction = msc_new_transaction(modsec, rules); msc_process_connection(transaction, "127.0.0.1"); msc_process_uri(transaction, "http://www.modsecurity.org/test?key1=value1&key2=value2&key3=value3&test=args&test=test"); msc_process_request_headers(transaction); msc_process_request_body(transaction); msc_process_response_headers(transaction); msc_process_response_body(transaction); return 0; } ``` # Contributing You are more than welcome to contribute to this project and look forward to growing the community around this new version of ModSecurity. Areas of interest include: New functionalities, fixes, bug report, support for beginning users, or anything that you are willing to help with. ## Providing patches We prefer to have your patch within the GitHub infrastructure to facilitate our review work, and our Q.A. integration. GitHub provides excellent documentation on how to perform “Pull Requests”, more information available here: https://help.github.com/articles/using-pull-requests/ Please respect the coding style. Pull requests can include various commits, so provide one fix or one piece of functionality per commit. Please do not change anything outside the scope of your target work (e.g. coding style in a function that you have passed by). For further information about the coding style used in this project, please check: https://www.chromium.org/blink/coding-style Provides explanative commit messages. Your first line should give the highlights of your patch, 3rd and on give a more detailed explanation/technical details about your patch. Patch explanation is valuable during the review process. ### Don’t know where to start? Within our code there are various items marked as TODO or FIXME that may need your attention. Check the list of items by performing a grep: ``` $ cd /path/to/modsecurity-nginx $ egrep -Rin "TODO|FIXME" -R * ``` A TODO list is also available as part of the Doxygen documentation. ### Testing your patch Along with the manual testing, we strongly recommend you to use the our regression tests and unit tests. If you have implemented an operator, don’t forget to create unit tests for it. If you implement anything else, it is encouraged that you develop complimentary regression tests for it. The regression test and unit test utilities are native and do not demand any external tool or script, although you need to fetch the test cases from other repositories, as they are shared with other versions of ModSecurity, those others repositories git submodules. To fetch the submodules repository and run the utilities, follow the commands listed below: ```shell $ cd /path/to/your/ModSecurity $ git submodule update --init --recursive $ make check ``` ### Debugging Before start the debugging process, make sure of where your bug is. The problem could be on your connector or in libmodsecurity. In order to identify where the bug is, it is recommended that you develop a regression test that mimics the scenario where the bug is happening. If the bug is reproducible with the regression-test utility, then it will be far simpler to debug and ensure that it never occurs again. On Linux it is recommended that anyone undertaking debugging utilize gdb and/or valgrind as needed. During the configuration/compilation time, you may want to disable the compiler optimization making your “back traces” populated with readable data. Use the CFLAGS to disable the compilation optimization parameters: ```shell $ export CFLAGS="-g -O0" $ ./build.sh $ ./configure --enable-assertions=yes $ make $ sudo make install ``` "Assertions allow us to document assumptions and to spot violations early in the development process. What is more, assertions allow us to spot violations with a minimum of effort." https://dl.acm.org/doi/pdf/10.1145/240964.240969 It is recommended to use assertions where applicable, and to enable them with '--enable-assertions=yes' during the testing and debugging workflow. ### Benchmarking The source tree includes a Benchmark tool that can help measure library performance. The tool is located in the `test/benchmark/` directory. The build process also creates the binary here, so you will have the tool after the compilation is finished. To run, just type: ```shell cd test/benchmark $ ./benchmark Doing 1000000 transactions... ``` You can also pass a lower value: ```shell $ ./benchmark 1000 Doing 1000 transactions... ``` To measure the time: ```shell $ time ./benchmark 1000 Doing 1000 transactions... real 0m0.351s user 0m0.337s sys 0m0.022s ``` This is very fast because the benchmark uses the minimal `modsecurity.conf.default` configuration, which doesn't include too many rules: ```shell $ cat basic_rules.conf Include "../../modsecurity.conf-recommended" ``` To measure with real rules, run one of the download scripts in the same directory: ```shell $ ./download-owasp-v3-rules.sh Cloning into 'owasp-v3'... remote: Enumerating objects: 33007, done. remote: Counting objects: 100% (2581/2581), done. remote: Compressing objects: 100% (907/907), done. remote: Total 33007 (delta 2151), reused 2004 (delta 1638), pack-reused 30426 Receiving objects: 100% (33007/33007), 9.02 MiB | 16.21 MiB/s, done. Resolving deltas: 100% (25927/25927), done. Switched to a new branch 'tag3.0.2' /path/to/ModSecurity/test/benchmark Done. $ cat basic_rules.conf Include "../../modsecurity.conf-recommended" Include "owasp-v3/crs-setup.conf.example" Include "owasp-v3/rules/*.conf" ``` Now the command will give much higher value. #### How the benchmark works The tool is a straightforward wrapper application that utilizes the library. It creates a ModSecurity instance and a RuleSet instance, then runs a loop based on the specified number. Within this loop, it creates a Transaction object to emulate real HTTP transactions. Each transaction is an HTTP/1.1 GET request with some GET parameters. Common headers are added, followed by the response headers and an XML body. Between phases, the tool checks whether an intervention has occurred. All transactions are created with the same data. Note that the tool does not call the last phase (logging). Please remember to reset `basic_rules.conf` if you want to try with a different ruleset. ## Reporting Issues If you are facing a configuration issue or something is not working as you expected to be, please use the ModSecurity user’s mailing list. Issues on GitHub are also welcomed, but we prefer to have user ask questions on the mailing list first so that you can reach an entire community. Also don’t forget to look for existing issues before open a new one. If you are going to open a new issue on GitHub, don’t forget to tell us the version of your libmodsecurity and the version of a specific connector if there is one. ### Security issue Please do not make public any security issue. Contact us at: modsecurity@owasp.org reporting the issue. Once the problem is fixed your credit will be given. ## Feature request We are open to discussing any new feature request with the community via the mailing lists. You can alternativly, feel free to open GitHub issues requesting new features. Before opening a new issue, please check if there is one already opened on the same topic. ## Bindings The libModSecurity design allows the integration with bindings. There is an effort to avoid breaking API [binary] compatibility to make an easy integration with possible bindings. Currently, there are a few notable projects maintained by the community: * Python - https://github.com/actions-security/pymodsecurity * Rust - https://github.com/rkrishn7/rust-modsecurity * Varnish - https://github.com/xdecock/vmod-modsecurity ## Packaging Having our packages in distros on time is a desire that we have, so let us know if there is anything we can do to facilitate your work as a packager. ## Sponsor Note Development of ModSecurity is sponsored by Trustwave. Sponsorship will end July 1, 2024. Additional information can be found here https://www.trustwave.com/en-us/resources/security-resources/software-updates/end-of-sale-and-trustwave-support-for-modsecurity-web-application-firewall/ ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Supported Versions The latest versions of both v2.9.x and v3.0.x are supported. ## Reporting a Vulnerability For information on how to report a security issue, please see https://github.com/owasp-modsecurity/ModSecurity#security-issue ================================================ FILE: build/.empty ================================================ ================================================ FILE: build/ax_cxx_compile_stdcxx.m4 ================================================ # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the specified # version of the C++ standard. If necessary, add switches to CXX and # CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for # the respective C++ standard version. # # The second argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with # preference for no added switch, and then for an extended mode. # # The third argument, if specified 'mandatory' or if left unspecified, # indicates that baseline support for the specified C++ standard is # required and that the macro should error out if no mode with that # support is found. If specified 'optional', then configuration proceeds # regardless, after defining HAVE_CXX${VERSION} if and only if a # supporting mode is found. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler # Copyright (c) 2016, 2018 Krzesimir Nowak # Copyright (c) 2019 Enji Cooper # Copyright (c) 2020 Jason Merrill # Copyright (c) 2021 Jörn Heusipp # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 18 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], [$1], [20], [ax_cxx_compile_alternatives="20"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], [$2], [noext], [], [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no m4_if([$2], [], [dnl AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ax_cv_cxx_compile_cxx$1, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [ax_cv_cxx_compile_cxx$1=yes], [ax_cv_cxx_compile_cxx$1=no])]) if test x$ax_cv_cxx_compile_cxx$1 = xyes; then ac_success=yes fi]) m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do switch="-std=gnu++${alternative}" cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done fi]) m4_if([$2], [ext], [], [dnl if test x$ac_success = xno; then dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" dnl MSVC needs -std:c++NN for C++17 and later (default is C++14) for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do if test x"$switch" = xMSVC; then dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide dnl with -std=c++17. We suffix the cache variable name with _MSVC to dnl avoid this. switch=-std:c++${alternative} cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC]) else cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) fi AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" CXX="$CXX $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], [eval $cachevar=yes], [eval $cachevar=no]) CXX="$ac_save_CXX"]) if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi]) AC_LANG_POP([C++]) if test x$ax_cxx_compile_cxx$1_required = xtrue; then if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) fi fi if test x$ac_success = xno; then HAVE_CXX$1=0 AC_MSG_NOTICE([No compiler with C++$1 support was found]) else HAVE_CXX$1=1 AC_DEFINE(HAVE_CXX$1,1, [define if the compiler supports basic C++$1 syntax]) fi AC_SUBST(HAVE_CXX$1) ]) dnl Test body for checking C++11 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) dnl Test body for checking C++17 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ) dnl Test body for checking C++20 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 ) dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L ]]) dnl Tests for new features in C++14 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ // 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 ]]) dnl Tests for new features in C++17 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201703L && !defined _MSC_VER #error "This is not a C++17 compiler" #else #include #include #include namespace cxx17 { namespace test_constexpr_lambdas { constexpr int foo = [](){return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // __cplusplus < 201703L && !defined _MSC_VER ]]) dnl Tests for new features in C++20 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 202002L && !defined _MSC_VER #error "This is not a C++20 compiler" #else #include namespace cxx20 { // As C++20 supports feature test macros in the standard, there is no // immediate need to actually test for feature availability on the // Autoconf side. } // namespace cxx20 #endif // __cplusplus < 202002L && !defined _MSC_VER ]]) ================================================ FILE: build/ax_prog_doxygen.m4 ================================================ # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html # =========================================================================== # # SYNOPSIS # # DX_INIT_DOXYGEN(PROJECT-NAME, DOXYFILE-PATH, [OUTPUT-DIR]) # DX_DOXYGEN_FEATURE(ON|OFF) # DX_DOT_FEATURE(ON|OFF) # DX_HTML_FEATURE(ON|OFF) # DX_CHM_FEATURE(ON|OFF) # DX_CHI_FEATURE(ON|OFF) # DX_MAN_FEATURE(ON|OFF) # DX_RTF_FEATURE(ON|OFF) # DX_XML_FEATURE(ON|OFF) # DX_PDF_FEATURE(ON|OFF) # DX_PS_FEATURE(ON|OFF) # # DESCRIPTION # # The DX_*_FEATURE macros control the default setting for the given # Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for # generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML # help (for MS users), 'CHI' for generating a seperate .chi file by the # .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate # output formats. The environment variable DOXYGEN_PAPER_SIZE may be # specified to override the default 'a4wide' paper size. # # By default, HTML, PDF and PS documentation is generated as this seems to # be the most popular and portable combination. MAN pages created by # Doxygen are usually problematic, though by picking an appropriate subset # and doing some massaging they might be better than nothing. CHM and RTF # are specific for MS (note that you can't generate both HTML and CHM at # the same time). The XML is rather useless unless you apply specialized # post-processing to it. # # The macros mainly control the default state of the feature. The use can # override the default by specifying --enable or --disable. The macros # ensure that contradictory flags are not given (e.g., # --enable-doxygen-html and --enable-doxygen-chm, # --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each # feature will be automatically disabled (with a warning) if the required # programs are missing. # # Once all the feature defaults have been specified, call DX_INIT_DOXYGEN # with the following parameters: a one-word name for the project for use # as a filename base etc., an optional configuration file name (the # default is 'Doxyfile', the same as Doxygen's default), and an optional # output directory name (the default is 'doxygen-doc'). # # Automake Support # # The following is a template aminclude.am file for use with Automake. # Make targets and variables values are controlled by the various # DX_COND_* conditionals set by autoconf. # # The provided targets are: # # doxygen-doc: Generate all doxygen documentation. # # doxygen-run: Run doxygen, which will generate some of the # documentation (HTML, CHM, CHI, MAN, RTF, XML) # but will not do the post processing required # for the rest of it (PS, PDF, and some MAN). # # doxygen-man: Rename some doxygen generated man pages. # # doxygen-ps: Generate doxygen PostScript documentation. # # doxygen-pdf: Generate doxygen PDF documentation. # # Note that by default these are not integrated into the automake targets. # If doxygen is used to generate man pages, you can achieve this # integration by setting man3_MANS to the list of man pages generated and # then adding the dependency: # # $(man3_MANS): doxygen-doc # # This will cause make to run doxygen and generate all the documentation. # # The following variable is intended for use in Makefile.am: # # DX_CLEANFILES = everything to clean. # # Then add this variable to MOSTLYCLEANFILES. # # ----- begin aminclude.am ------------------------------------- # # ## --------------------------------- ## # ## Format-independent Doxygen rules. ## # ## --------------------------------- ## # # if DX_COND_doc # # ## ------------------------------- ## # ## Rules specific for HTML output. ## # ## ------------------------------- ## # # if DX_COND_html # # DX_CLEAN_HTML = @DX_DOCDIR@/html # # endif DX_COND_html # # ## ------------------------------ ## # ## Rules specific for CHM output. ## # ## ------------------------------ ## # # if DX_COND_chm # # DX_CLEAN_CHM = @DX_DOCDIR@/chm # # if DX_COND_chi # # DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi # # endif DX_COND_chi # # endif DX_COND_chm # # ## ------------------------------ ## # ## Rules specific for MAN output. ## # ## ------------------------------ ## # # if DX_COND_man # # DX_CLEAN_MAN = @DX_DOCDIR@/man # # endif DX_COND_man # # ## ------------------------------ ## # ## Rules specific for RTF output. ## # ## ------------------------------ ## # # if DX_COND_rtf # # DX_CLEAN_RTF = @DX_DOCDIR@/rtf # # endif DX_COND_rtf # # ## ------------------------------ ## # ## Rules specific for XML output. ## # ## ------------------------------ ## # # if DX_COND_xml # # DX_CLEAN_XML = @DX_DOCDIR@/xml # # endif DX_COND_xml # # ## ----------------------------- ## # ## Rules specific for PS output. ## # ## ----------------------------- ## # # if DX_COND_ps # # DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps # # DX_PS_GOAL = doxygen-ps # # doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps # # @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag # cd @DX_DOCDIR@/latex; \ # rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ # $(DX_LATEX) refman.tex; \ # $(MAKEINDEX_PATH) refman.idx; \ # $(DX_LATEX) refman.tex; \ # countdown=5; \ # while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ # refman.log > /dev/null 2>&1 \ # && test $$countdown -gt 0; do \ # $(DX_LATEX) refman.tex; \ # countdown=`expr $$countdown - 1`; \ # done; \ # $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi # # endif DX_COND_ps # # ## ------------------------------ ## # ## Rules specific for PDF output. ## # ## ------------------------------ ## # # if DX_COND_pdf # # DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf # # DX_PDF_GOAL = doxygen-pdf # # doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf # # @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag # cd @DX_DOCDIR@/latex; \ # rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ # $(DX_PDFLATEX) refman.tex; \ # $(DX_MAKEINDEX) refman.idx; \ # $(DX_PDFLATEX) refman.tex; \ # countdown=5; \ # while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ # refman.log > /dev/null 2>&1 \ # && test $$countdown -gt 0; do \ # $(DX_PDFLATEX) refman.tex; \ # countdown=`expr $$countdown - 1`; \ # done; \ # mv refman.pdf ../@PACKAGE@.pdf # # endif DX_COND_pdf # # ## ------------------------------------------------- ## # ## Rules specific for LaTeX (shared for PS and PDF). ## # ## ------------------------------------------------- ## # # if DX_COND_latex # # DX_CLEAN_LATEX = @DX_DOCDIR@/latex # # endif DX_COND_latex # # .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) # # .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) # # doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag # # doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) # # @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS) # rm -rf @DX_DOCDIR@ # $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG) # echo Timestamp >$@ # # DX_CLEANFILES = \ # @DX_DOCDIR@/@PACKAGE@.tag \ # -r \ # $(DX_CLEAN_HTML) \ # $(DX_CLEAN_CHM) \ # $(DX_CLEAN_CHI) \ # $(DX_CLEAN_MAN) \ # $(DX_CLEAN_RTF) \ # $(DX_CLEAN_XML) \ # $(DX_CLEAN_PS) \ # $(DX_CLEAN_PDF) \ # $(DX_CLEAN_LATEX) # # endif DX_COND_doc # # ----- end aminclude.am --------------------------------------- # # LICENSE # # Copyright (c) 2009 Oren Ben-Kiki # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 13 ## ----------## ## Defaults. ## ## ----------## DX_ENV="" AC_DEFUN([DX_FEATURE_doc], ON) AC_DEFUN([DX_FEATURE_dot], OFF) AC_DEFUN([DX_FEATURE_man], OFF) AC_DEFUN([DX_FEATURE_html], ON) AC_DEFUN([DX_FEATURE_chm], OFF) AC_DEFUN([DX_FEATURE_chi], OFF) AC_DEFUN([DX_FEATURE_rtf], OFF) AC_DEFUN([DX_FEATURE_xml], OFF) AC_DEFUN([DX_FEATURE_pdf], ON) AC_DEFUN([DX_FEATURE_ps], ON) ## --------------- ## ## Private macros. ## ## --------------- ## # DX_ENV_APPEND(VARIABLE, VALUE) # ------------------------------ # Append VARIABLE="VALUE" to DX_ENV for invoking doxygen. AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])]) # DX_DIRNAME_EXPR # --------------- # Expand into a shell expression prints the directory part of a path. AC_DEFUN([DX_DIRNAME_EXPR], [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']]) # DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF) # ------------------------------------- # Expands according to the M4 (static) status of the feature. AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])]) # DX_REQUIRE_PROG(VARIABLE, PROGRAM) # ---------------------------------- # Require the specified program to be found for the DX_CURRENT_FEATURE to work. AC_DEFUN([DX_REQUIRE_PROG], [ AC_PATH_TOOL([$1], [$2]) if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION]) AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0) fi ]) # DX_TEST_FEATURE(FEATURE) # ------------------------ # Expand to a shell expression testing whether the feature is active. AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1]) # DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE) # ------------------------------------------------- # Verify that a required features has the right state before trying to turn on # the DX_CURRENT_FEATURE. AC_DEFUN([DX_CHECK_DEPEND], [ test "$DX_FLAG_$1" = "$2" \ || AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1, requires, contradicts) doxygen-DX_CURRENT_FEATURE]) ]) # DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE) # ---------------------------------------------------------- # Turn off the DX_CURRENT_FEATURE if the required feature is off. AC_DEFUN([DX_CLEAR_DEPEND], [ test "$DX_FLAG_$1" = "$2" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0) ]) # DX_FEATURE_ARG(FEATURE, DESCRIPTION, # CHECK_DEPEND, CLEAR_DEPEND, # REQUIRE, DO-IF-ON, DO-IF-OFF) # -------------------------------------------- # Parse the command-line option controlling a feature. CHECK_DEPEND is called # if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND), # otherwise CLEAR_DEPEND is called to turn off the default state if a required # feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional # requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and # DO-IF-ON or DO-IF-OFF are called according to the final state of the feature. AC_DEFUN([DX_ARG_ABLE], [ AC_DEFUN([DX_CURRENT_FEATURE], [$1]) AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2]) AC_ARG_ENABLE(doxygen-$1, [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1], [--enable-doxygen-$1]), DX_IF_FEATURE([$1], [don't $2], [$2]))], [ case "$enableval" in #( y|Y|yes|Yes|YES) AC_SUBST([DX_FLAG_$1], 1) $3 ;; #( n|N|no|No|NO) AC_SUBST([DX_FLAG_$1], 0) ;; #( *) AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1]) ;; esac ], [ AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)]) $4 ]) if DX_TEST_FEATURE([$1]); then $5 : fi AM_CONDITIONAL(DX_COND_$1, DX_TEST_FEATURE([$1])) if DX_TEST_FEATURE([$1]); then $6 : else $7 : fi ]) ## -------------- ## ## Public macros. ## ## -------------- ## # DX_XXX_FEATURE(DEFAULT_STATE) # ----------------------------- AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])]) AC_DEFUN([DX_DOT_FEATURE], [AC_DEFUN([DX_FEATURE_dot], [$1])]) AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])]) AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])]) AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])]) AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])]) AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])]) AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])]) AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])]) # DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR]) # --------------------------------------------------------- # PROJECT also serves as the base name for the documentation files. # The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc". AC_DEFUN([DX_INIT_DOXYGEN], [ # Files: AC_SUBST([DX_PROJECT], [$1]) AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])]) AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])]) # Environment variables used inside doxygen.cfg: DX_ENV_APPEND(SRCDIR, $srcdir) DX_ENV_APPEND(PROJECT, $DX_PROJECT) DX_ENV_APPEND(DOCDIR, $DX_DOCDIR) DX_ENV_APPEND(VERSION, $PACKAGE_VERSION) # Doxygen itself: DX_ARG_ABLE(doc, [generate any doxygen documentation], [], [], [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen) DX_REQUIRE_PROG([DX_PERL], perl)], [DX_ENV_APPEND(PERL_PATH, $DX_PERL)]) # Dot for graphics: DX_ARG_ABLE(dot, [generate graphics for doxygen documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_DOT], dot)], [DX_ENV_APPEND(HAVE_DOT, YES) DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])], [DX_ENV_APPEND(HAVE_DOT, NO)]) # Man pages generation: DX_ARG_ABLE(man, [generate doxygen manual pages], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [], [DX_ENV_APPEND(GENERATE_MAN, YES)], [DX_ENV_APPEND(GENERATE_MAN, NO)]) # RTF file generation: DX_ARG_ABLE(rtf, [generate doxygen RTF documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [], [DX_ENV_APPEND(GENERATE_RTF, YES)], [DX_ENV_APPEND(GENERATE_RTF, NO)]) # XML file generation: DX_ARG_ABLE(xml, [generate doxygen XML documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [], [DX_ENV_APPEND(GENERATE_XML, YES)], [DX_ENV_APPEND(GENERATE_XML, NO)]) # (Compressed) HTML help generation: DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_HHC], hhc)], [DX_ENV_APPEND(HHC_PATH, $DX_HHC) DX_ENV_APPEND(GENERATE_HTML, YES) DX_ENV_APPEND(GENERATE_HTMLHELP, YES)], [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)]) # Seperate CHI file generation. DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file], [DX_CHECK_DEPEND(chm, 1)], [DX_CLEAR_DEPEND(chm, 1)], [], [DX_ENV_APPEND(GENERATE_CHI, YES)], [DX_ENV_APPEND(GENERATE_CHI, NO)]) # Plain HTML pages generation: DX_ARG_ABLE(html, [generate doxygen plain HTML documentation], [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)], [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)], [], [DX_ENV_APPEND(GENERATE_HTML, YES)], [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)]) # PostScript file generation: DX_ARG_ABLE(ps, [generate doxygen PostScript documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_LATEX], latex) DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) DX_REQUIRE_PROG([DX_DVIPS], dvips) DX_REQUIRE_PROG([DX_EGREP], egrep)]) # PDF file generation: DX_ARG_ABLE(pdf, [generate doxygen PDF documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex) DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) DX_REQUIRE_PROG([DX_EGREP], egrep)]) # LaTeX generation for PS and/or PDF: AM_CONDITIONAL(DX_COND_latex, DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf)) if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then DX_ENV_APPEND(GENERATE_LATEX, YES) else DX_ENV_APPEND(GENERATE_LATEX, NO) fi # Paper size for PS and/or PDF: AC_ARG_VAR(DOXYGEN_PAPER_SIZE, [a4wide (default), a4, letter, legal or executive]) case "$DOXYGEN_PAPER_SIZE" in #( "") AC_SUBST(DOXYGEN_PAPER_SIZE, "") ;; #( a4wide|a4|letter|legal|executive) DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE) ;; #( *) AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE']) ;; esac #For debugging: #echo DX_FLAG_doc=$DX_FLAG_doc #echo DX_FLAG_dot=$DX_FLAG_dot #echo DX_FLAG_man=$DX_FLAG_man #echo DX_FLAG_html=$DX_FLAG_html #echo DX_FLAG_chm=$DX_FLAG_chm #echo DX_FLAG_chi=$DX_FLAG_chi #echo DX_FLAG_rtf=$DX_FLAG_rtf #echo DX_FLAG_xml=$DX_FLAG_xml #echo DX_FLAG_pdf=$DX_FLAG_pdf #echo DX_FLAG_ps=$DX_FLAG_ps #echo DX_ENV=$DX_ENV ]) ================================================ FILE: build/ax_valgrind_check.m4 ================================================ # =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html # =========================================================================== # # SYNOPSIS # # AX_VALGRIND_DFLT(memcheck|helgrind|drd|sgcheck, on|off) # AX_VALGRIND_CHECK() # # DESCRIPTION # # AX_VALGRIND_CHECK checks whether Valgrind is present and, if so, allows # running `make check` under a variety of Valgrind tools to check for # memory and threading errors. # # Defines VALGRIND_CHECK_RULES which should be substituted in your # Makefile; and $enable_valgrind which can be used in subsequent configure # output. VALGRIND_ENABLED is defined and substituted, and corresponds to # the value of the --enable-valgrind option, which defaults to being # enabled if Valgrind is installed and disabled otherwise. Individual # Valgrind tools can be disabled via --disable-valgrind-, the # default is configurable via the AX_VALGRIND_DFLT command or is to use # all commands not disabled via AX_VALGRIND_DFLT. All AX_VALGRIND_DFLT # calls must be made before the call to AX_VALGRIND_CHECK. # # If unit tests are written using a shell script and automake's # LOG_COMPILER system, the $(VALGRIND) variable can be used within the # shell scripts to enable Valgrind, as described here: # # https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html # # Usage example: # # configure.ac: # # AX_VALGRIND_DFLT([sgcheck], [off]) # AX_VALGRIND_CHECK # # Makefile.am: # # @VALGRIND_CHECK_RULES@ # VALGRIND_SUPPRESSIONS_FILES = my-project.supp # EXTRA_DIST = my-project.supp # # This results in a "check-valgrind" rule being added to any Makefile.am # which includes "@VALGRIND_CHECK_RULES@" (assuming the module has been # configured with --enable-valgrind). Running `make check-valgrind` in # that directory will run the module's test suite (`make check`) once for # each of the available Valgrind tools (out of memcheck, helgrind and drd) # while the sgcheck will be skipped unless enabled again on the # commandline with --enable-valgrind-sgcheck. The results for each check # will be output to test-suite-$toolname.log. The target will succeed if # there are zero errors and fail otherwise. # # Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in # memcheck, helgrind, drd and sgcheck. These are useful because often only # some of those tools can be ran cleanly on a codebase. # # The macro supports running with and without libtool. # # LICENSE # # Copyright (c) 2014, 2015, 2016 Philip Withnall # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 13 dnl Configured tools m4_define([valgrind_tool_list], [[memcheck], [helgrind], [drd], [sgcheck]]) m4_set_add_all([valgrind_exp_tool_set], [sgcheck]) m4_foreach([vgtool], [valgrind_tool_list], [m4_define([en_dflt_valgrind_]vgtool, [on])]) AC_DEFUN([AX_VALGRIND_DFLT],[ m4_define([en_dflt_valgrind_$1], [$2]) ])dnl AC_DEFUN([AX_VALGRIND_CHECK],[ dnl Check for --enable-valgrind AC_ARG_ENABLE([valgrind], [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])], [enable_valgrind=$enableval],[enable_valgrind=]) AS_IF([test "$enable_valgrind" != "no"],[ # Check for Valgrind. AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind]) AS_IF([test "$VALGRIND" = ""],[ AS_IF([test "$enable_valgrind" = "yes"],[ AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind]) ],[ enable_valgrind=no ]) ],[ enable_valgrind=yes ]) ]) AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"]) AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind]) # Check for Valgrind tools we care about. [valgrind_enabled_tools=] m4_foreach([vgtool],[valgrind_tool_list],[ AC_ARG_ENABLE([valgrind-]vgtool, m4_if(m4_defn([en_dflt_valgrind_]vgtool),[off],dnl [AS_HELP_STRING([--enable-valgrind-]vgtool, [Whether to use ]vgtool[ during the Valgrind tests])],dnl [AS_HELP_STRING([--disable-valgrind-]vgtool, [Whether to skip ]vgtool[ during the Valgrind tests])]), [enable_valgrind_]vgtool[=$enableval], [enable_valgrind_]vgtool[=]) AS_IF([test "$enable_valgrind" = "no"],[ enable_valgrind_]vgtool[=no], [test "$enable_valgrind_]vgtool[" ]dnl m4_if(m4_defn([en_dflt_valgrind_]vgtool), [off], [= "yes"], [!= "no"]),[ AC_CACHE_CHECK([for Valgrind tool ]vgtool, [ax_cv_valgrind_tool_]vgtool,[ ax_cv_valgrind_tool_]vgtool[=no m4_set_contains([valgrind_exp_tool_set],vgtool, [m4_define([vgtoolx],[exp-]vgtool)], [m4_define([vgtoolx],vgtool)]) AS_IF([`$VALGRIND --tool=]vgtoolx[ --help >/dev/null 2>&1`],[ ax_cv_valgrind_tool_]vgtool[=yes ]) ]) AS_IF([test "$ax_cv_valgrind_tool_]vgtool[" = "no"],[ AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ AC_MSG_ERROR([Valgrind does not support ]vgtool[; reconfigure with --disable-valgrind-]vgtool) ],[ enable_valgrind_]vgtool[=no ]) ],[ enable_valgrind_]vgtool[=yes ]) ]) AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ valgrind_enabled_tools="$valgrind_enabled_tools ]m4_bpatsubst(vgtool,[^exp-])[" ]) AC_SUBST([ENABLE_VALGRIND_]vgtool,[$enable_valgrind_]vgtool) ]) AC_SUBST([valgrind_tools],["]m4_join([ ], valgrind_tool_list)["]) AC_SUBST([valgrind_enabled_tools],[$valgrind_enabled_tools]) [VALGRIND_CHECK_RULES=' # Valgrind check # # Optional: # - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions # files to load. (Default: empty) # - VALGRIND_FLAGS: General flags to pass to all Valgrind tools. # (Default: --num-callers=30) # - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of: # memcheck, helgrind, drd, sgcheck). (Default: various) # Optional variables VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES)) VALGRIND_FLAGS ?= --num-callers=30 VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no VALGRIND_helgrind_FLAGS ?= --history-level=approx VALGRIND_drd_FLAGS ?= VALGRIND_sgcheck_FLAGS ?= # Internal use valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools))) valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS) valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS) valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS) valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS) valgrind_quiet = $(valgrind_quiet_$(V)) valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY)) valgrind_quiet_0 = --quiet valgrind_v_use = $(valgrind_v_use_$(V)) valgrind_v_use_ = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY)) valgrind_v_use_0 = @echo " USE " $(patsubst check-valgrind-%,%,$''@):; # Support running with and without libtool. ifneq ($(LIBTOOL),) valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute else valgrind_lt = endif # Use recursive makes in order to ignore errors during check check-valgrind: ifeq ($(VALGRIND_ENABLED),yes) -$(A''M_V_at)$(foreach tool,$(valgrind_enabled_tools), \ $(MAKE) $(AM_MAKEFLAGS) -k check-valgrind-$(tool); \ ) else @echo "Need to reconfigure with --enable-valgrind" endif # Valgrind running VALGRIND_TESTS_ENVIRONMENT = \ $(TESTS_ENVIRONMENT) \ env VALGRIND=$(VALGRIND) \ G_SLICE=always-malloc,debug-blocks \ G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly VALGRIND_LOG_COMPILER = test/test-suite.sh $(VALGRIND_SUPPRESSIONS) $(VALGRIND_FLAGS) # $(valgrind_lt) \ # $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS) define valgrind_tool_rule = check-valgrind-$(1): ifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes) $$(valgrind_v_use)$$(MAKE) check-TESTS \ TESTS_ENVIRONMENT="$$(VALGRIND_TESTS_ENVIRONMENT)" \ LOG_COMPILER="$$(VALGRIND_LOG_COMPILER)" \ LOG_FLAGS="$$(valgrind_$(1)_flags)" \ TEST_SUITE_LOG=test-suite-$(1).log else ifeq ($$(VALGRIND_ENABLED),yes) @echo "Need to reconfigure with --enable-valgrind-$(1)" else @echo "Need to reconfigure with --enable-valgrind" endif endef $(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool)))) A''M_DISTCHECK_CONFIGURE_FLAGS ?= A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind MOSTLYCLEANFILES ?= MOSTLYCLEANFILES += $(valgrind_log_files) .PHONY: check-valgrind $(add-prefix check-valgrind-,$(valgrind_tools)) '] AC_SUBST([VALGRIND_CHECK_RULES]) m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])]) ]) ================================================ FILE: build/curl.m4 ================================================ dnl Check for CURL Libraries dnl Sets: dnl CURL_CFLAGS dnl CURL_LDADD dnl CURL_LDFLAGS dnl CURL_VERSION dnl CURL_DISPLAY dnl CURL_FOUND AC_DEFUN([CHECK_CURL], [ MSC_CHECK_LIB([CURL], [libcurl], [curl/curl.h], [curl], [-DWITH_CURL], [7.15.1]) # Post-processing: TLSv1.2 version check if test "x${CURL_FOUND}" = "x1" && test -n "${CURL_VERSION}"; then AC_MSG_CHECKING([if libcurl supports TLSv1.2]) _msc_curl_tlsv2_ver=`echo 7.34.0 | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` _msc_curl_ver=`echo ${CURL_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` if test "${_msc_curl_tlsv2_ver}" -le "${_msc_curl_ver}" 2>/dev/null; then AC_MSG_RESULT([yes]) CURL_CFLAGS="${CURL_CFLAGS} -DWITH_CURL_SSLVERSION_TLSv1_2" else AC_MSG_RESULT([no]) fi # Check/warn if GnuTLS is used AC_MSG_CHECKING([if libcurl is linked with gnutls]) _msc_curl_uses_gnutls=`echo ${CURL_LDADD} | grep gnutls | wc -l` if test "$_msc_curl_uses_gnutls" -ne 0; then AC_MSG_RESULT([yes]) AC_MSG_NOTICE([NOTE: curl linked with gnutls may be buggy, openssl recommended]) else AC_MSG_RESULT([no]) fi fi ]) # AC_DEFUN [CHECK_CURL] ================================================ FILE: build/libgeoip.m4 ================================================ dnl Check for GeoIP Libraries dnl Sets: dnl GEOIP_CFLAGS dnl GEOIP_LDADD dnl GEOIP_LDFLAGS dnl GEOIP_VERSION dnl GEOIP_DISPLAY dnl GEOIP_FOUND AC_DEFUN([PROG_GEOIP], [ MSC_CHECK_LIB([GEOIP], [geoip2 geoip GeoIP], [GeoIPCity.h], [GeoIP], [-DWITH_GEOIP]) ]) # AC_DEFUN [PROG_GEOIP] ================================================ FILE: build/libmaxmind.m4 ================================================ dnl Check for MaxMind Libraries dnl Sets: dnl MAXMIND_CFLAGS dnl MAXMIND_LDADD dnl MAXMIND_LDFLAGS dnl MAXMIND_VERSION dnl MAXMIND_DISPLAY dnl MAXMIND_FOUND AC_DEFUN([PROG_MAXMIND], [ MSC_CHECK_LIB([MAXMIND], [libmaxminddb], [maxminddb.h], [maxminddb], [-DWITH_MAXMIND]) ]) # AC_DEFUN [PROG_MAXMIND] ================================================ FILE: build/libxml.m4 ================================================ dnl Check for LIBXML2 Libraries dnl Sets: dnl LIBXML2_CFLAGS dnl LIBXML2_LDADD dnl LIBXML2_LDFLAGS dnl LIBXML2_VERSION dnl LIBXML2_DISPLAY dnl LIBXML2_FOUND AC_DEFUN([CHECK_LIBXML2], [ MSC_CHECK_LIB([LIBXML2], [libxml-2.0], [libxml/parser.h], [xml2], [-DWITH_LIBXML2], [2.6.29], [libxml]) ]) # AC_DEFUN [CHECK_LIBXML2] ================================================ FILE: build/lmdb.m4 ================================================ dnl Check for LMDB Libraries dnl LMDB is disabled by default; only enabled when --with-lmdb is given. dnl Sets: dnl LMDB_CFLAGS dnl LMDB_LDADD dnl LMDB_LDFLAGS dnl LMDB_VERSION dnl LMDB_DISPLAY dnl LMDB_FOUND AC_DEFUN([PROG_LMDB], [ # LMDB is opt-in: auto-detect finds it but we only activate when # --with-lmdb or --with-lmdb=PATH is given explicitly. MSC_CHECK_LIB([LMDB], [lmdb], [lmdb.h], [lmdb], [-DWITH_LMDB]) # If LMDB was found by auto-detection (no explicit --with-lmdb) treat it # as disabled since LMDB is opt-in. _msc_lmdb_with_val="$with_lmdb" if test "x${_msc_lmdb_with_val}" = "x" && test "x${LMDB_FOUND}" = "x1"; then LMDB_FOUND=2 LMDB_CFLAGS="" LMDB_LDADD="" LMDB_LDFLAGS="" LMDB_DISPLAY="" AC_MSG_NOTICE([LMDB is disabled by default. Use --with-lmdb to enable.]) fi ]) # AC_DEFUN [PROG_LMDB] ================================================ FILE: build/lua.m4 ================================================ dnl Check for LUA Libraries dnl Sets: dnl LUA_CFLAGS dnl LUA_LDADD dnl LUA_LDFLAGS dnl LUA_DISPLAY dnl LUA_FOUND AC_DEFUN([CHECK_LUA], [ MSC_CHECK_LIB([LUA], [lua54 lua5.4 lua-5.4 lua53 lua5.3 lua-5.3 lua52 lua5.2 lua-5.2 lua51 lua5.1 lua-5.1 luajit lua], [lua.h], [lua5.4 lua5.3 lua5.2 lua5.1 luajit-5.1 lua], [-DWITH_LUA]) # Post-processing: detect Lua version and add version-specific defines if test "x${LUA_FOUND}" = "x1"; then # Use version already detected by MSC_CHECK_LIB (from pkg-config) if available if test -n "${LUA_VERSION}" && test "x${LUA_VERSION}" != "xunknown"; then case ${LUA_VERSION} in 5.1*) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ;; 5.2*) LUA_CFLAGS="-DWITH_LUA_5_2 ${LUA_CFLAGS}" ;; 5.3*) LUA_CFLAGS="-DWITH_LUA_5_3 ${LUA_CFLAGS}" ;; 5.4*) LUA_CFLAGS="-DWITH_LUA_5_4 ${LUA_CFLAGS}" ;; 2.0*) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ;; 2.1*) LUA_CFLAGS="-DWITH_LUA_5_1 -DWITH_LUA_JIT_2_1 ${LUA_CFLAGS}" ;; esac AC_MSG_NOTICE([LUA version: ${LUA_VERSION}]) fi # If no version detected yet, try compile tests if test -z "${LUA_VERSION}" || test "x${LUA_VERSION}" = "xunknown"; then LUA_VERSION="" _msc_save_CFLAGS=$CFLAGS CFLAGS="${LUA_CFLAGS} ${CFLAGS}" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ #if (LUA_VERSION_NUM == 504) return 0; #else #error not 5.4 #endif ]])], [ _msc_lua_ver=504 ], [ _msc_lua_ver="" ]) if test -z "$_msc_lua_ver"; then AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ #if (LUA_VERSION_NUM == 503) return 0; #else #error not 5.3 #endif ]])], [ _msc_lua_ver=503 ], [ _msc_lua_ver="" ]) fi if test -z "$_msc_lua_ver"; then AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ #if (LUA_VERSION_NUM == 502) return 0; #else #error not 5.2 #endif ]])], [ _msc_lua_ver=502 ], [ _msc_lua_ver="" ]) fi if test -z "$_msc_lua_ver"; then AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ #if (LUA_VERSION_NUM == 501) return 0; #else #error not 5.1 #endif ]])], [ _msc_lua_ver=501 ], [ _msc_lua_ver="" ]) fi CFLAGS=$_msc_save_CFLAGS case $_msc_lua_ver in 501) LUA_CFLAGS="-DWITH_LUA_5_1 ${LUA_CFLAGS}" ;; 502) LUA_CFLAGS="-DWITH_LUA_5_2 ${LUA_CFLAGS}" ;; 503) LUA_CFLAGS="-DWITH_LUA_5_3 ${LUA_CFLAGS}" ;; 504) LUA_CFLAGS="-DWITH_LUA_5_4 ${LUA_CFLAGS}" ;; esac if test -n "$_msc_lua_ver"; then AC_MSG_NOTICE([LUA version from compile test: $_msc_lua_ver]) fi fi LUA_DISPLAY="${LUA_LDADD} ${LUA_LDFLAGS}, ${LUA_CFLAGS}" fi ]) # AC_DEFUN [CHECK_LUA] ================================================ FILE: build/msc_find_lib.m4 ================================================ dnl MSC_CHECK_LIB: Generic library detection macro dnl dnl MSC_CHECK_LIB(NAME, PKG_NAMES, HEADER, LIB_NAMES, EXTRA_CFLAGS, dnl [MIN_VERSION], [WITH_NAME]) dnl dnl Detects a library via pkg-config first, then falls back to manual dnl file-system scanning. Preserves the --with-LIB=PATH|yes|no interface. dnl dnl Sets and AC_SUBSTs: dnl ${NAME}_CFLAGS, ${NAME}_LDADD, ${NAME}_LDFLAGS, dnl ${NAME}_VERSION, ${NAME}_DISPLAY, ${NAME}_FOUND (0/1/2) dnl dnl NAME - Variable prefix (e.g., YAJL, CURL, LIBXML2) dnl PKG_NAMES - Space-separated pkg-config names to try dnl HEADER - Header file to look for (e.g., yajl/yajl_parse.h) dnl LIB_NAMES - Space-separated library names for -l flags dnl EXTRA_CFLAGS - Additional CFLAGS when found (e.g., -DWITH_YAJL) dnl MIN_VERSION - Optional minimum version for pkg-config check dnl WITH_NAME - Optional --with-X name if different from lowercased NAME AC_DEFUN([MSC_CHECK_LIB], [ m4_pushdef([_MSC_NAME], [$1])dnl m4_pushdef([_MSC_PKG_NAMES], [$2])dnl m4_pushdef([_MSC_HEADER], [$3])dnl m4_pushdef([_MSC_LIB_NAMES], [$4])dnl m4_pushdef([_MSC_EXTRA_CFLAGS], [$5])dnl m4_pushdef([_MSC_MIN_VERSION], [$6])dnl m4_pushdef([_MSC_WITH_NAME], [m4_default([$7], m4_tolower([$1]))])dnl m4_pushdef([_MSC_POSSIBLE_PATHS], [/usr/local /usr /opt /opt/local /usr/lib /usr/local/lib /usr/lib64])dnl m4_pushdef([_MSC_POSSIBLE_EXTENSIONS], [so la sl dll dylib])dnl # Initialize variables $1_VERSION="" $1_CFLAGS="" $1_LDADD="" $1_LDFLAGS="" $1_DISPLAY="" $1_FOUND=0 _msc_[]m4_tolower($1)[]_mandatory="" _msc_[]m4_tolower($1)[]_disabled="" AC_ARG_WITH( _MSC_WITH_NAME, [AS_HELP_STRING([--with-]_MSC_WITH_NAME[=PATH], [Path to ]_MSC_NAME[ prefix. Use 'no' to disable.])]) # Get the value of the --with flag _msc_with_val="$with_[]m4_translit(_MSC_WITH_NAME, [-], [_])" if test "x${_msc_with_val}" = "xno"; then AC_MSG_NOTICE([$1 support disabled via --without-]_MSC_WITH_NAME) _msc_[]m4_tolower($1)[]_disabled=yes elif test "x${_msc_with_val}" = "xyes"; then _msc_[]m4_tolower($1)[]_mandatory=yes AC_MSG_NOTICE([$1 support marked as mandatory]) # Try pkg-config _MSC_TRY_PKG_CONFIG([$1], [_MSC_PKG_NAMES], [_MSC_MIN_VERSION]) if test -z "${$1_VERSION}"; then _MSC_TRY_MANUAL([$1], [_MSC_HEADER], [_MSC_LIB_NAMES]) fi elif test "x${_msc_with_val}" = "x"; then # Auto-detect AC_MSG_NOTICE([Auto-detecting $1...]) _MSC_TRY_PKG_CONFIG([$1], [_MSC_PKG_NAMES], [_MSC_MIN_VERSION]) if test -z "${$1_VERSION}"; then _MSC_TRY_MANUAL([$1], [_MSC_HEADER], [_MSC_LIB_NAMES]) fi else # Specific path provided _msc_[]m4_tolower($1)[]_mandatory=yes _MSC_TRY_PKG_CONFIG_AT([$1], [_MSC_PKG_NAMES], [_MSC_MIN_VERSION], [${_msc_with_val}]) if test -z "${$1_VERSION}"; then _MSC_CHECK_AT([$1], [_MSC_HEADER], [_MSC_LIB_NAMES], [${_msc_with_val}]) fi fi # Evaluate results if test -n "${$1_LDADD}" || test -n "${$1_VERSION}"; then $1_FOUND=1 AC_MSG_NOTICE([using $1 v${$1_VERSION}]) $1_CFLAGS="_MSC_EXTRA_CFLAGS ${$1_CFLAGS}" if test -z "${$1_DISPLAY}"; then $1_DISPLAY="${$1_LDADD}, ${$1_CFLAGS}" fi AC_SUBST($1_VERSION) AC_SUBST($1_LDADD) AC_SUBST($1_LDFLAGS) AC_SUBST($1_CFLAGS) AC_SUBST($1_DISPLAY) elif test -n "${_msc_[]m4_tolower($1)[]_disabled}"; then $1_FOUND=2 elif test -n "${_msc_[]m4_tolower($1)[]_mandatory}"; then AC_MSG_ERROR([$1 was explicitly requested but not found]) else AC_MSG_NOTICE([$1 library not found]) $1_FOUND=0 fi AC_SUBST($1_FOUND) m4_popdef([_MSC_POSSIBLE_EXTENSIONS])dnl m4_popdef([_MSC_POSSIBLE_PATHS])dnl m4_popdef([_MSC_WITH_NAME])dnl m4_popdef([_MSC_MIN_VERSION])dnl m4_popdef([_MSC_EXTRA_CFLAGS])dnl m4_popdef([_MSC_LIB_NAMES])dnl m4_popdef([_MSC_HEADER])dnl m4_popdef([_MSC_PKG_NAMES])dnl m4_popdef([_MSC_NAME])dnl ]) # MSC_CHECK_LIB dnl _MSC_TRY_PKG_CONFIG(NAME, PKG_NAMES, MIN_VERSION) dnl Try to find the library via pkg-config AC_DEFUN([_MSC_TRY_PKG_CONFIG], [ if test -n "${PKG_CONFIG}"; then _msc_pkg_name="" for _msc_p in $2; do if test -n "$3"; then if ${PKG_CONFIG} --exists "${_msc_p} >= $3" 2>/dev/null; then _msc_pkg_name="${_msc_p}" break fi else if ${PKG_CONFIG} --exists "${_msc_p}" 2>/dev/null; then _msc_pkg_name="${_msc_p}" break fi fi done if test -n "${_msc_pkg_name}"; then $1_VERSION="`${PKG_CONFIG} ${_msc_pkg_name} --modversion`" $1_CFLAGS="`${PKG_CONFIG} ${_msc_pkg_name} --cflags`" $1_LDADD="`${PKG_CONFIG} ${_msc_pkg_name} --libs-only-l`" $1_LDFLAGS="`${PKG_CONFIG} ${_msc_pkg_name} --libs-only-L --libs-only-other`" $1_DISPLAY="${$1_LDADD}, ${$1_CFLAGS}" AC_MSG_NOTICE([$1 found via pkg-config: ${_msc_pkg_name} v${$1_VERSION}]) fi fi ]) # _MSC_TRY_PKG_CONFIG dnl _MSC_TRY_PKG_CONFIG_AT(NAME, PKG_NAMES, MIN_VERSION, PATH) dnl Try pkg-config with PKG_CONFIG_PATH set to a specific location AC_DEFUN([_MSC_TRY_PKG_CONFIG_AT], [ if test -n "${PKG_CONFIG}"; then _msc_save_pkg_config_path="${PKG_CONFIG_PATH}" PKG_CONFIG_PATH="$4/lib/pkgconfig:$4/lib64/pkgconfig:$4/share/pkgconfig:${PKG_CONFIG_PATH}" export PKG_CONFIG_PATH _MSC_TRY_PKG_CONFIG([$1], [$2], [$3]) PKG_CONFIG_PATH="${_msc_save_pkg_config_path}" export PKG_CONFIG_PATH fi ]) # _MSC_TRY_PKG_CONFIG_AT dnl _MSC_TRY_MANUAL(NAME, HEADER, LIB_NAMES) dnl Try to find the library by scanning common paths AC_DEFUN([_MSC_TRY_MANUAL], [ for _msc_search_path in /usr/local /usr /opt /opt/local /usr/lib /usr/local/lib /usr/lib64; do _MSC_CHECK_AT([$1], [$2], [$3], [${_msc_search_path}]) if test -n "${$1_VERSION}"; then break fi # Also check if LDADD was set (version may not always be detected manually) if test -n "${$1_LDADD}"; then break fi done ]) # _MSC_TRY_MANUAL dnl _MSC_CHECK_AT(NAME, HEADER, LIB_NAMES, PATH) dnl Check for a library at a specific path AC_DEFUN([_MSC_CHECK_AT], [ _msc_check_lib_path="" _msc_check_lib_name="" _msc_check_lib_file="" _msc_check_inc_path="" # Search for library files for _msc_ext in so la sl dll dylib; do for _msc_ln in $3; do for _msc_try_path in \ "$4/lib${_msc_ln}.${_msc_ext}" \ "$4/lib/lib${_msc_ln}.${_msc_ext}" \ "$4/lib64/lib${_msc_ln}.${_msc_ext}" \ "$4/lib/x86_64-linux-gnu/lib${_msc_ln}.${_msc_ext}" \ "$4/lib/i386-linux-gnu/lib${_msc_ln}.${_msc_ext}"; do if test -e "${_msc_try_path}"; then _msc_check_lib_path="`dirname ${_msc_try_path}`" _msc_check_lib_name="${_msc_ln}" _msc_check_lib_file="${_msc_try_path}" break 3 fi done done done # Search for header file _msc_header_base="`basename $2`" _msc_header_dir="`dirname $2`" if test "${_msc_header_dir}" = "."; then # Simple header name (e.g., "lmdb.h") if test -e "$4/include/$2"; then _msc_check_inc_path="$4/include" elif test -e "$4/$2"; then _msc_check_inc_path="$4" fi else # Header with subdirectory (e.g., "yajl/yajl_parse.h") if test -e "$4/include/$2"; then _msc_check_inc_path="$4/include" elif test -e "$4/$2"; then _msc_check_inc_path="$4" fi fi if test -n "${_msc_check_lib_path}" && test -n "${_msc_check_inc_path}"; then AC_MSG_NOTICE([$1 headers found at: ${_msc_check_inc_path}]) AC_MSG_NOTICE([$1 library found at: ${_msc_check_lib_file}]) $1_CFLAGS="-I${_msc_check_inc_path}" $1_LDADD="-l${_msc_check_lib_name}" $1_LDFLAGS="-L${_msc_check_lib_path}" $1_DISPLAY="${_msc_check_lib_file}, ${_msc_check_inc_path}" # Version is unknown from manual detection if test -z "${$1_VERSION}"; then $1_VERSION="unknown" fi fi ]) # _MSC_CHECK_AT dnl MSC_STATUS_LIB(DISPLAY_NAME, VAR_PREFIX) dnl Print a status line for the configure summary AC_DEFUN([MSC_STATUS_LIB], [ if test "x${$2_FOUND}" = "x0"; then echo " + $1 ....not found" fi if test "x${$2_FOUND}" = "x1"; then AS_ECHO_N([" + $1 ....found "]) if ! test "x${$2_VERSION}" = "x"; then echo "v${$2_VERSION}" else echo "" fi echo " ${$2_DISPLAY}" fi if test "x${$2_FOUND}" = "x2"; then echo " + $1 ....disabled" fi ]) # MSC_STATUS_LIB dnl MSC_ARG_ENABLE_BOOL(NAME, HELP_TEXT, DEFAULT, VARIABLE) dnl Wrapper for boolean AC_ARG_ENABLE options AC_DEFUN([MSC_ARG_ENABLE_BOOL], [ AC_ARG_ENABLE($1, [AS_HELP_STRING([--enable-$1],[$2])], [case "${enableval}" in yes) $4=true ;; no) $4=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-$1]) ;; esac], [$4=$3]) ]) # MSC_ARG_ENABLE_BOOL ================================================ FILE: build/pcre.m4 ================================================ dnl Check for PCRE Libraries dnl Sets: dnl PCRE_CFLAGS dnl PCRE_LDADD dnl PCRE_LDFLAGS dnl PCRE_VERSION dnl PCRE_FOUND PCRE_CONFIG="" PCRE_VERSION="" PCRE_CPPFLAGS="" PCRE_CFLAGS="" PCRE_LDFLAGS="" PCRE_LDADD="" PCRE_LD_PATH="" AC_DEFUN([CHECK_PCRE], [ MSC_CHECK_LIB([PCRE], [libpcre], [pcre.h], [pcre], [-DWITH_PCRE]) # Post-processing: JIT detection if test "x${PCRE_FOUND}" = "x1" && test -n "${PCRE_VERSION}"; then AC_MSG_CHECKING([for PCRE JIT]) _msc_save_CFLAGS=$CFLAGS _msc_save_LDFLAGS=$LDFLAGS _msc_save_LIBS=$LIBS CFLAGS="${PCRE_CFLAGS} ${CFLAGS}" LDFLAGS="${PCRE_LDADD} ${LDFLAGS}" LIBS="${PCRE_LDADD} ${LIBS}" AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ #include ]], [[ pcre_jit_exec(NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL); ]])], [ _msc_pcre_jit_available=yes ], [:] ) if test "x$_msc_pcre_jit_available" = "xyes"; then AC_MSG_RESULT([yes]) PCRE_CFLAGS="${PCRE_CFLAGS} -DPCRE_HAVE_JIT" else AC_MSG_RESULT([no]) fi CFLAGS=$_msc_save_CFLAGS LDFLAGS=$_msc_save_LDFLAGS LIBS=$_msc_save_LIBS fi AC_SUBST(PCRE_CONFIG) AC_SUBST(PCRE_CPPFLAGS) AC_SUBST(PCRE_LD_PATH) ]) # AC_DEFUN [CHECK_PCRE] ================================================ FILE: build/pcre2.m4 ================================================ dnl Check for PCRE2 Libraries dnl PCRE2 is enabled by default (mandatory unless --with-pcre is used). dnl Sets: dnl PCRE2_CFLAGS dnl PCRE2_LDADD dnl PCRE2_LDFLAGS dnl PCRE2_VERSION dnl PCRE2_DISPLAY dnl PCRE2_FOUND AC_DEFUN([PROG_PCRE2], [ MSC_CHECK_LIB([PCRE2], [libpcre2-8 pcre2-8 pcre2], [pcre2.h], [pcre2-8], []) ]) # AC_DEFUN [PROG_PCRE2] ================================================ FILE: build/release.sh ================================================ #!/bin/bash git clean -xfdi git submodule foreach --recursive git clean -xfdi VERSION=`git describe --tags` DIR_NAME="modsecurity-$VERSION" TAR_NAME="modsecurity-$VERSION.tar.gz" MY_DIR=${PWD##*/} ./build.sh cd .. tar --transform "s/^$MY_DIR/$DIR_NAME/" -cvzf $TAR_NAME --exclude .git $MY_DIR sha256sum $TAR_NAME > $TAR_NAME.sha256 gpg --detach-sign -a $TAR_NAME cd - echo $TAR_NAME ": done." ================================================ FILE: build/ssdeep.m4 ================================================ dnl Check for SSDEEP Libraries dnl Sets: dnl SSDEEP_CFLAGS dnl SSDEEP_LDADD dnl SSDEEP_LDFLAGS dnl SSDEEP_DISPLAY dnl SSDEEP_FOUND AC_DEFUN([CHECK_SSDEEP], [ MSC_CHECK_LIB([SSDEEP], [fuzzy], [fuzzy.h], [fuzzy], [-DWITH_SSDEEP]) ]) # AC_DEFUN [CHECK_SSDEEP] ================================================ FILE: build/win32/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.24) set(BASE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) option(WITH_LMDB "Include LMDB support" OFF) option(WITH_LUA "Include LUA support" ON) option(WITH_LIBXML2 "Include LibXML2 support" ON) option(WITH_MAXMIND "Include MaxMind support" ON) option(WITH_CURL "Include CURL support" ON) option(USE_ASAN "Build with Address Sanitizer" OFF) # common compiler settings # NOTE: MBEDTLS_CONFIG_FILE is not only required to compile the mbedtls subset in others, but also # when their headers are included while compiling libModSecurity add_compile_definitions(WIN32 _CRT_SECURE_NO_WARNINGS MBEDTLS_CONFIG_FILE="mbedtls/mbedtls_config.h") # set standards conformance preprocessor & compiler to align with cross-compiled codebase # NOTE: otherwise visual c++'s default compiler/preprocessor behaviour generates C4067 warnings # (unexpected tokens following preprocessor directive - expected a newline) add_compile_options(/Zc:preprocessor /permissive-) if(USE_ASAN) add_compile_options(/fsanitize=address) add_link_options(/INFERASANLIBS /INCREMENTAL:no) endif() # libinjection project(libinjection C) set(LIBINJECTION_DIR ${BASE_DIR}/others/libinjection) add_library(libinjection STATIC ${LIBINJECTION_DIR}/src/libinjection_sqli.c ${LIBINJECTION_DIR}/src/libinjection_xss.c ${LIBINJECTION_DIR}/src/libinjection_html5.c) # get libinjection version with git describe execute_process( COMMAND git describe WORKING_DIRECTORY ${LIBINJECTION_DIR} OUTPUT_VARIABLE LIBINJECTION_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) message("-- Detecting libinjection version - ${LIBINJECTION_VERSION}") target_compile_definitions(libinjection PRIVATE LIBINJECTION_VERSION="${LIBINJECTION_VERSION}") # mbedtls (mbedcrypto) project(mbedcrypto C) set(MBEDTLS_DIR ${BASE_DIR}/others/mbedtls) add_library(mbedcrypto STATIC ${MBEDTLS_DIR}/library/base64.c ${MBEDTLS_DIR}/library/sha1.c ${MBEDTLS_DIR}/library/md5.c ${MBEDTLS_DIR}/library/platform_util.c ${MBEDTLS_DIR}/library/constant_time.c) target_include_directories(mbedcrypto PRIVATE ${MBEDTLS_DIR}/include) # get mbedtls version with git describe execute_process( COMMAND git describe WORKING_DIRECTORY ${MBEDTLS_DIR} OUTPUT_VARIABLE MBEDTLS_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) message("-- Detecting Mbed TLS version - ${MBEDTLS_VERSION}") # # libModSecurity # project(libModSecurity VERSION 3.0.12 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED On) set(CMAKE_CXX_EXTENSIONS Off) set(PACKAGE_BUGREPORT "security@modsecurity.org") set(PACKAGE_NAME "modsecurity") set(PACKAGE_VERSION "${PROJECT_VERSION}") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}") set(HAVE_YAJL 1) # should always be one, mandatory dependency set(HAVE_GEOIP 0) # should always be zero, no conan package available set(HAVE_SSDEEP 0) # should always be zero, no conan package available macro(enable_feature flag option) if(${option}) set(${flag} 1) # ON else() set(${flag} 0) # OFF endif() endmacro() enable_feature(HAVE_LMDB ${WITH_LMDB}) enable_feature(HAVE_LUA ${WITH_LUA}) enable_feature(HAVE_LIBXML2 ${WITH_LIBXML2}) enable_feature(HAVE_MAXMIND ${WITH_MAXMIND}) enable_feature(HAVE_CURL ${WITH_CURL}) include(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake) configure_file(config.h.cmake ${BASE_DIR}/src/config.h) find_package(PCRE2 REQUIRED) find_package(Poco REQUIRED) find_package(dirent REQUIRED) # used only by tests (check dirent::dirent refernces) macro(include_package package flag) if(${flag}) find_package(${package} REQUIRED) endif() endmacro() include_package(yajl HAVE_YAJL) include_package(libxml2 HAVE_LIBXML2) include_package(lua HAVE_LUA) include_package(CURL HAVE_CURL) include_package(lmdb HAVE_LMDB) include_package(maxminddb HAVE_MAXMIND) # library # # NOTE: required to generate libModSecurity's import library (libModSecurity.lib), used by tests to link with shared library set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) file(GLOB_RECURSE libModSecuritySources ${BASE_DIR}/src/*.cc) add_library(libModSecurity SHARED ${libModSecuritySources}) target_compile_definitions(libModSecurity PRIVATE WITH_PCRE2) target_include_directories(libModSecurity PRIVATE ${BASE_DIR} ${BASE_DIR}/headers ${BASE_DIR}/others ${MBEDTLS_DIR}/include) target_link_libraries(libModSecurity PRIVATE pcre2::pcre2 libinjection mbedcrypto Poco::Poco Iphlpapi.lib) macro(add_package_dependency project compile_definition link_library flag) if(${flag}) target_compile_definitions(${project} PRIVATE ${compile_definition}) target_link_libraries(${project} PRIVATE ${link_library}) endif() endmacro() add_package_dependency(libModSecurity WITH_YAJL yajl::yajl HAVE_YAJL) add_package_dependency(libModSecurity WITH_LIBXML2 LibXml2::LibXml2 HAVE_LIBXML2) add_package_dependency(libModSecurity WITH_LUA lua::lua HAVE_LUA) if(HAVE_LUA) target_compile_definitions(libModSecurity PRIVATE WITH_LUA_5_4) endif() add_package_dependency(libModSecurity MSC_WITH_CURL CURL::libcurl HAVE_CURL) add_package_dependency(libModSecurity WITH_LMDB lmdb::lmdb HAVE_LMDB) add_package_dependency(libModSecurity WITH_MAXMIND maxminddb::maxminddb HAVE_MAXMIND) # tests # project(libModSecurityTests) function(setTestTargetProperties executable) target_compile_definitions(${executable} PRIVATE WITH_PCRE2) target_include_directories(${executable} PRIVATE ${BASE_DIR} ${BASE_DIR}/headers) target_link_libraries(${executable} PRIVATE libModSecurity pcre2::pcre2 dirent::dirent) add_package_dependency(${executable} WITH_YAJL yajl::yajl HAVE_YAJL) endfunction() # unit tests file(GLOB unitTestSources ${BASE_DIR}/test/unit/*.cc) add_executable(unit_tests ${unitTestSources} ${BASE_DIR}/test/common/custom_debug_log.cc) setTestTargetProperties(unit_tests) target_compile_options(unit_tests PRIVATE /wd4805) # regression tests file(GLOB regressionTestsSources ${BASE_DIR}/test/regression/*.cc) add_executable(regression_tests ${regressionTestsSources} ${BASE_DIR}/test/common/custom_debug_log.cc) setTestTargetProperties(regression_tests) macro(add_regression_test_capability compile_definition flag) if(${flag}) target_compile_definitions(regression_tests PRIVATE ${compile_definition}) endif() endmacro() add_regression_test_capability(WITH_LUA HAVE_LUA) add_regression_test_capability(WITH_CURL HAVE_CURL) add_regression_test_capability(WITH_LMDB HAVE_LMDB) add_regression_test_capability(WITH_MAXMIND HAVE_MAXMIND) enable_testing() file(READ ${BASE_DIR}/test/test-suite.in TEST_FILES_RAW) string(REPLACE "\n" ";" TEST_FILES ${TEST_FILES_RAW}) foreach(TEST_FILE ${TEST_FILES}) # ignore comment lines string(FIND ${TEST_FILE} "#" is_comment) if(NOT is_comment EQUAL 0) string(FIND ${TEST_FILE} "TESTS+=" is_valid_prefix) if(NOT is_valid_prefix EQUAL 0) message(FATAL_ERROR "Invalid prefix in line: ${TEST_FILE}") endif() # remove 'TESTS+=' prefix and 'test/' too because tests are launched # from that directory string(SUBSTRING ${TEST_FILE} 12 -1 TEST_FILE) # test name get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE) # determine test runner based on test path prefix string(FIND ${TEST_FILE} "test-cases/regression/" is_regression_test) if(is_regression_test EQUAL 0) set(TEST_RUNNER "regression_tests") else() set(TEST_RUNNER "unit_tests") endif() add_test(NAME ${TEST_NAME} COMMAND ${TEST_RUNNER} ${TEST_FILE} WORKING_DIRECTORY ${BASE_DIR}/test) endif() endforeach() # benchmark add_executable(benchmark ${BASE_DIR}/test/benchmark/benchmark.cc) setTestTargetProperties(benchmark) # rules_optimization add_executable(rules_optimization ${BASE_DIR}/test/optimization/optimization.cc) setTestTargetProperties(rules_optimization) # examples # project(libModSecurityExamples) function(setExampleTargetProperties executable) target_include_directories(${executable} PRIVATE ${BASE_DIR} ${BASE_DIR}/headers) target_link_libraries(${executable} PRIVATE libModSecurity) endfunction() # simple_example_using_c add_executable(simple_example_using_c ${BASE_DIR}/examples/simple_example_using_c/test.c) setExampleTargetProperties(simple_example_using_c) # using_bodies_in_chunks add_executable(using_bodies_in_chunks ${BASE_DIR}/examples/using_bodies_in_chunks/simple_request.cc) setExampleTargetProperties(using_bodies_in_chunks) # reading_logs_via_rule_message add_executable(reading_logs_via_rule_message ${BASE_DIR}/examples/reading_logs_via_rule_message/simple_request.cc) setExampleTargetProperties(reading_logs_via_rule_message) # reading_logs_with_offset add_executable(reading_logs_with_offset ${BASE_DIR}/examples/reading_logs_with_offset/read.cc) setExampleTargetProperties(reading_logs_with_offset) # multithread add_executable(multithread ${BASE_DIR}/examples/multithread/multithread.cc) setExampleTargetProperties(multithread) # tools # # rules_check add_executable(rules_check ${BASE_DIR}/tools/rules-check/rules-check.cc) target_include_directories(rules_check PRIVATE ${BASE_DIR} ${BASE_DIR}/headers) target_link_libraries(rules_check PRIVATE libModSecurity) ================================================ FILE: build/win32/ConfigureChecks.cmake ================================================ include(CheckIncludeFile) include(CheckIncludeFiles) check_include_file("dlfcn.h" HAVE_DLFCN_H) check_include_file("inttypes.h" HAVE_INTTYPES_H) check_include_file("stdint.h" HAVE_STDINT_H) check_include_file("stdio.h" HAVE_STDIO_H) check_include_file("stdlib.h" HAVE_STDLIB_H) check_include_file("string" HAVE_STRING) check_include_file("strings.h" HAVE_STRINGS_H) check_include_file("string.h" HAVE_STRING_H) check_include_file("sys/stat.h" HAVE_SYS_STAT_H) check_include_file("sys/types.h" HAVE_SYS_TYPES_H) check_include_file("sys/utsname.h" HAVE_SYS_UTSNAME_H) check_include_file("unistd.h" HAVE_UNISTD_H) #/* Define to 1 if you have the ANSI C header files. */ check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS) ================================================ FILE: build/win32/README.md ================================================ # libModSecurity Windows build information The Windows build of libModSecurity uses Build Tools for Visual Studio 2022 (for Visual C++ & CMake) and Conan package manager. ## Contents - [Prerequisites](#prerequisites) - [Build](#build) - [Optional features](#optional-features) - [Address Sanitizer](#address-sanitizer) - [Docker container](#docker-container) ## Prerequisites * [Build Tools for Visual Studio 2022](https://aka.ms/vs/17/release/vs_buildtools.exe) * Install *Desktop development with C++* workload, which includes: * MSVC C++ compiler * Windows SDK * CMake * Address Sanitizer * [Conan package manager 2.10.2](https://github.com/conan-io/conan/releases/download/2.10.2/conan-2.10.2-windows-x86_64-installer.exe) * Install and then setup the default Conan profile to use the MSVC C++ compiler: 1. Open a command-prompt and set the MSVC C++ compiler environment by executing: `C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat` 2. Execute: `conan profile detect --force` * [Git for Windows 2.44.0](https://github.com/git-for-windows/git/releases/download/v2.44.0.windows.1/Git-2.44.0-64-bit.exe) * To clone the libModSecurity repository. * NOTE: Make sure to initialize and update submodules (to get `libinjection` and regression tests) * `git submodule init` * `git submodule update` ## Build Install the prerequisites listed in the previous section, checkout libModSecurity and from the directory where it's located execute: ``` vcbuild.bat [build_configuration] [arch] [USE_ASAN] ``` where `[build_configuration]` can be: `Release` (default), `RelWithDebInfo`, `MinSizeRel` or `Debug`, and `[arch]` can be: `x86_64` (default) or `x86`. Built files will be located in the directory: `build\win32\build\[build_configuration]` and include: * `libModSecurity.dll` * Executable files for test projects * `unit_tests.exe` * `regression_tests.exe` * `benchmark.exe` * `rules_optimization.exe` * Executable files for examples * `simple_example_using_c.exe` * `using_bodies_in_chunks.exe` * `reading_logs_via_rule_message.exe` * `reading_logs_with_offset.exe` * `multithread.exe` * Executable files for tools * `rules_check.exe` NOTE: When building a different configuration, it's recommended to reset: * the build directory: `build\win32\build` * previously built conan packages executing the command: * `conan remove * -c` ### Optional features By default the following all the following features are enabled by including the associated third-party library through a Conan package: * libxml2 2.12.6 for XML processing support * libcurl 8.6.0 to support http requests from rules * libmaxminddb 1.9.1 to support reading MaxMind DB files. * LUA 5.4.6 to enable rules to run scripts in this language for extensibility * lmdb 0.9.31 in-memory database Each of these can be turned off by updating the associated `HAVE_xxx` variable (setting it to zero) in the beginning of the libModSecurity section of `CMakeLists.txt`. ### Address Sanitizer [AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) (aka ASan) is a memory error detector for C/C++. To generate a build with *Address Sanitizer*, add the `USE_ASAN` optional third argument to `vcbuild.bat`. For example: * `vcbuild.bat Debug x86_64 USE_ASAN` NOTE: `USE_ASAN` does not work with `Release` & `MinSizeRel` configurations because they do not include debug info (it is only compatible with `Debug` & `RelWithDebInfo` builds). * References * [AddressSanitizer | Microsoft Learn](https://learn.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-170) * [AddressSanitizer for Windows: x64 and Debug Build Support - C++ Team Blog (microsoft.com)](https://devblogs.microsoft.com/cppblog/asan-for-windows-x64-and-debug-build-support/) * [AddressSanitizer language, build, and debugging reference | Microsoft Learn](https://learn.microsoft.com/en-us/cpp/sanitizers/asan-building?view=msvc-170) ### Docker container A `Dockerfile` configuration file is provided in the `docker` subdir that creates a Windows container image which installs the [prerequisites](#prerequisites) and builds libModSecurity and other binaries. NOTE: Windows containers are supported in Docker Desktop for Windows, using the *Switch to Windows containers...* option on the context menu of the system tray icon. To build the docker image, execute the following command (from the `build\win32\docker` directory): * `docker build -t libmodsecurity:latest -m 4GB .` * Build type, architecture and build with Address Sanitizer can be configured through build arguments (`BUILD_TYPE`, `ARCH` & `USE_ASAN` respectively). For example, to generate a debug build, add the following argument: * `--build-arg BUILD_TYPE=Debug` Once the image is generated, the library and associated binaries (tests & examples) are located in the `C:\src\ModSecurity\build\win32\build\[build_type]` directory. To extract the library (`libModSecurity.dll`) from the image, you can execute the following commands: * `docker container create --name [container_name] libmodsecurity` * `docker cp [container_name]:C:\src\ModSecurity\build\win32\build\[build_type]\libModSecurity.dll .` * NOTE: If you leave out the `libModSecurity.dll` filename out, you can copy all the built binaries (including examples & tests). Additionally, the image can be used interactively for additional development work by executing: * `docker run -it libmodsecurity` ================================================ FILE: build/win32/conanfile.txt ================================================ [requires] yajl/2.1.0 pcre2/10.42 libxml2/2.12.6 lua/5.4.6 libcurl/8.6.0 lmdb/0.9.31 libmaxminddb/1.9.1 dirent/1.24 poco/1.13.3 [generators] CMakeDeps CMakeToolchain ================================================ FILE: build/win32/config.h.cmake ================================================ /* config.h.cmake. Based upon generated config.h.in. */ #ifndef MODSECURITY_CONFIG_H #define MODSECURITY_CONFIG_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_DLFCN_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_IOSTREAM /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDINT_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDIO_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_UTSNAME_H /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H /* Define if GeoIP is available */ #cmakedefine HAVE_GEOIP /* Define if LMDB is available */ #cmakedefine HAVE_LMDB /* Define if LUA is available */ #cmakedefine HAVE_LUA /* Define if MaxMind is available */ #cmakedefine HAVE_MAXMIND /* Define if SSDEEP is available */ #cmakedefine HAVE_SSDEEP /* Define if YAJL is available */ #cmakedefine HAVE_YAJL /* Define if libcurl is available */ #cmakedefine HAVE_CURL /* Name of package */ #define PACKAGE "@PACKAGE_NAME@" /* Define to the address where bug reports for this package should be sent. */ #cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" /* Define to the full name of this package. */ #cmakedefine PACKAGE_NAME "@PACKAGE_NAME@" /* Define to the full name and version of this package. */ #cmakedefine PACKAGE_STRING "@PACKAGE_STRING@" /* Define to the one symbol short name of this package. */ #cmakedefine PACKAGE_TARNAME "@PACKAGE_TARNAME@" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" /* Define to 1 if you have the ANSI C header files. */ #ifndef STDC_HEADERS #cmakedefine STDC_HEADERS #endif #endif // ndef MODSECURITY_CONFIG_H ================================================ FILE: build/win32/docker/Dockerfile ================================================ # escape=` ARG FROM_IMAGE=mcr.microsoft.com/windows/servercore:ltsc2022 FROM ${FROM_IMAGE} # reset the shell. SHELL ["cmd", "/S", "/C"] # set up environment to collect install errors. COPY InstallBuildTools.cmd C:\TEMP\ ADD https://aka.ms/vscollect.exe C:\TEMP\collect.exe # download channel for fixed install. ARG CHANNEL_URL=https://aka.ms/vs/17/release/channel ADD ${CHANNEL_URL} C:\TEMP\VisualStudio.chman # download and install Build Tools for Visual Studio 2022 for native desktop workload. ADD https://aka.ms/vs/17/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe RUN C:\TEMP\InstallBuildTools.cmd C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache ` --channelUri C:\TEMP\VisualStudio.chman ` --installChannelUri C:\TEMP\VisualStudio.chman ` --add Microsoft.VisualStudio.Workload.VCTools ` --includeRecommended ` --installPath C:\BuildTools # download & install GIT ARG GIT_VERSION=2.44.0 ARG GIT_BINARY=Git-${GIT_VERSION}-64-bit.exe ARG GIT_URL=https://github.com/git-for-windows/git/releases/download/v${GIT_VERSION}.windows.1/${GIT_BINARY} COPY git.inf C:\TEMP\ ARG INSTALLER=C:\TEMP\${GIT_BINARY} ADD ${GIT_URL} ${INSTALLER} RUN %INSTALLER% /SP- /VERYSILENT /SUPPRESSMSGBOXES /NOCANCEL ` /NORESTART /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /LOADINF=git.inf # download & setup conan ARG CONAN_VERSION=2.10.2 ARG CONAN_BINARY=conan-${CONAN_VERSION}-windows-x86_64-installer.exe ARG CONAN_URL=https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/${CONAN_BINARY} ARG INSTALLER=C:\TEMP\${CONAN_BINARY} ADD ${CONAN_URL} ${INSTALLER} RUN %INSTALLER% /SP- /VERYSILENT /SUPPRESSMSGBOXES # setup conan profile RUN C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat && conan profile detect --force # download libModSecurity # # create src dir ARG SRC_DIR=C:\src WORKDIR C:\ RUN cmd.exe /C md %SRC_DIR% # libModSecurity WORKDIR ${SRC_DIR} ARG MOD_SECURITY_TAG=v3/master RUN git clone -c advice.detachedHead=false --depth 1 --branch %MOD_SECURITY_TAG% https://github.com/owasp-modsecurity/ModSecurity.git ARG MOD_SECURITY_DIR=${SRC_DIR}\ModSecurity WORKDIR ${MOD_SECURITY_DIR} # fetch submodules (bindings/python, others/libinjection, test/test-cases/secrules-language-tests) RUN git submodule init RUN git submodule update # build libraries # ARG BUILD_TYPE=Release ARG ARCH=x86_64 ARG USE_ASAN= RUN C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat && vcbuild.bat %BUILD_TYPE% %ARCH% %USE_ASAN% # test suite # # setup test environment RUN cmd.exe /C md \tmp RUN cmd.exe /C md \bin RUN cmd.exe /C copy "C:\Program Files\GIT\usr\bin" \bin > NUL RUN cmd.exe /C copy "C:\Program Files\GIT\usr\bin\echo.exe" \bin\echo > NUL # disable tests that don't work on windows ARG JQ_VERSION=1.7.1 ARG JQ_BINARY=jq-windows-amd64.exe ARG JQ_URL=https://github.com/jqlang/jq/releases/download/jq-${JQ_VERSION}/${JQ_BINARY} ARG JQ_BIN=C:\TEMP\jq.exe ADD ${JQ_URL} ${JQ_BIN} WORKDIR ${MOD_SECURITY_DIR}\test\test-cases\regression RUN %JQ_BIN% "map(if .title == \"Test match variable (1/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json RUN %JQ_BIN% "map(if .title == \"Test match variable (2/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json RUN %JQ_BIN% "map(if .title == \"Test match variable (3/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json RUN %JQ_BIN% "map(if .title == \"Variable offset - FILES_NAMES\" then .enabled = 0 else . end)" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json # run tests WORKDIR ${MOD_SECURITY_DIR}\build\win32\build RUN C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat && ctest -C %BUILD_TYPE% --output-on-failure # setup container's entrypoint # WORKDIR C:\ # Use developer command prompt and start PowerShell if no other command specified. ENTRYPOINT ["C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat", "&&", "powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"] ================================================ FILE: build/win32/docker/InstallBuildTools.cmd ================================================ @rem Copyright (C) Microsoft Corporation. All rights reserved. @rem Licensed under the MIT license. See LICENSE.txt in the project root for license information. @if not defined _echo echo off setlocal enabledelayedexpansion call %* if "%ERRORLEVEL%"=="3010" ( exit /b 0 ) else ( if not "%ERRORLEVEL%"=="0" ( set ERR=%ERRORLEVEL% call C:\TEMP\collect.exe -zip:C:\vslogs.zip exit /b !ERR! ) ) ================================================ FILE: build/win32/docker/git.inf ================================================ [Setup] Lang=default Dir=C:\Program Files\Git Group=Git NoIcons=0 SetupType=default Components=ext,ext\shellhere,ext\guihere,gitlfs,assoc,autoupdate Tasks= EditorOption=VIM CustomEditorPath= PathOption=Cmd SSHOption=OpenSSH TortoiseOption=false CURLOption=WinSSL CRLFOption=LFOnly BashTerminalOption=ConHost PerformanceTweaksFSCache=Enabled UseCredentialManager=Enabled EnableSymlinks=Disabled EnableBuiltinInteractiveAdd=Disabled ================================================ FILE: build/yajl.m4 ================================================ dnl Check for YAJL Libraries dnl Sets: dnl YAJL_CFLAGS dnl YAJL_LDADD dnl YAJL_LDFLAGS dnl YAJL_VERSION dnl YAJL_DISPLAY dnl YAJL_FOUND AC_DEFUN([PROG_YAJL], [ MSC_CHECK_LIB([YAJL], [yajl2 yajl], [yajl/yajl_parse.h], [yajl], [-DWITH_YAJL]) # FIX: if the include directory in CFLAGS ends with "include/yajl", # remove the suffix "/yajl". The library header files are included # using the prefix (e.g., #include ), and # this is even the case for the library itself (e.g., # yajl_tree.h includes yajl/yajl_common.h). _msc_yajl_new_cflags="" for _msc_yajl_flag in $YAJL_CFLAGS; do case "$_msc_yajl_flag" in -I*/include/yajl) _msc_yajl_new_flag="${_msc_yajl_flag%/yajl}" _msc_yajl_new_cflags="$_msc_yajl_new_cflags $_msc_yajl_new_flag" ;; *) _msc_yajl_new_cflags="$_msc_yajl_new_cflags $_msc_yajl_flag" ;; esac done YAJL_CFLAGS="$_msc_yajl_new_cflags" YAJL_DISPLAY="${YAJL_LDADD}, ${YAJL_CFLAGS}" ]) # AC_DEFUN [PROG_YAJL] ================================================ FILE: build.sh ================================================ #!/bin/sh rm -rf autom4te.cache rm -f aclocal.m4 cd src rm -f headers.mk echo "noinst_HEADERS = \\" > headers.mk ls -1 \ actions/*.h \ actions/ctl/*.h \ actions/data/*.h \ actions/disruptive/*.h \ actions/transformations/*.h \ debug_log/*.h \ audit_log/writer/*.h \ collection/backend/*.h \ operators/*.h \ parser/*.h \ request_body_processor/*.h \ utils/*.h \ variables/*.h \ engine/*.h \ *.h | tr "\012" " " >> headers.mk cd ../ case `uname` in Darwin*) glibtoolize --force --copy ;; *) libtoolize --force --copy ;; esac autoreconf --install autoheader automake --add-missing --foreign --copy --force-missing autoconf --force rm -rf autom4te.cache ================================================ FILE: configure.ac ================================================ # ModSecurity configure.ac AC_PREREQ([2.69]) # Get the hash of the last commit, to be used if it is not an # official release. AC_DEFUN([MSC_GIT_HASH], m4_esyscmd_s(git log -1 --format="%h" --abbrev-commit)) AC_DEFUN([MSC_MAJOR], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep "define MODSECURITY_MAJOR " | awk {'print $3'} | sed 's/\"//g')) AC_DEFUN([MSC_MINOR], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep "define MODSECURITY_MINOR " | awk {'print $3'} | sed 's/\"//g')) AC_DEFUN([MSC_PATCHLEVEL], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep "define MODSECURITY_PATCHLEVEL " | awk {'print $3'} | sed 's/\"//g')) AC_DEFUN([MSC_TAG], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep "define MODSECURITY_FTAG " | awk {'print $3'} | sed 's/\"//g')) # Version definition to be further used by AC_INIT and # .so file naming. m4_define([msc_version_major], [MSC_MAJOR]) m4_define([msc_version_minor], [MSC_MINOR]) m4_define([msc_version_patchlevel], [MSC_PATCHLEVEL]) m4_define([msc_version_c_plus_a], [m4_eval(msc_version_major + msc_version_minor)]) m4_define([msc_version], [msc_version_major.msc_version_minor]) m4_define([msc_version_with_patchlevel], [msc_version_major.msc_version_minor.msc_version_patchlevel]) m4_define([msc_version_git], [m4_esyscmd_s(git describe)]) m4_define([msc_version_info], [msc_version_c_plus_a:msc_version_patchlevel:msc_version_minor]) # Project Information AC_INIT([modsecurity], [3.0], [security@modsecurity.org]) # General definitions AC_CONFIG_MACRO_DIR([build]) AC_PREFIX_DEFAULT([/usr/local/modsecurity]) # General automake options. AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) # Check for dependencies (C++, AR, Lex, Yacc and Make) AC_PROG_CXX AM_PROG_AR AC_PROG_AWK AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_MKDIR_P PKG_PROG_PKG_CONFIG # Set C++ standard version and check if compiler supports it. AX_CXX_COMPILE_STDCXX(17, noext, mandatory) # Check for libinjection if ! test -f "${srcdir}/others/libinjection/src/libinjection_html5.c"; then AC_MSG_ERROR([\ libInjection was not found within ModSecurity source directory. libInjection code is available as part of ModSecurity source code in a format of a git-submodule. git-submodule allow us to specify the correct version of libInjection and still uses the libInjection repository to download it. You can download libInjection using git: $ git submodule update --init --recursive ]) fi # Libinjection version AC_DEFUN([LIBINJECTION_VERSION], m4_esyscmd_s(cd "others/libinjection" && git describe && cd ../..)) AC_SUBST([LIBINJECTION_VERSION]) # Check for Mbed TLS if ! test -f "${srcdir}/others/mbedtls/library/base64.c"; then AC_MSG_ERROR([\ Mbed TLS was not found within ModSecurity source directory. Mbed TLS code is available as part of ModSecurity source code in a format of a git-submodule. git-submodule allow us to specify the correct version of Mbed TLS and still uses the Mbed TLS repository to download it. You can download Mbed TLS using git: $ git submodule update --init --recursive ]) fi # Mbed TLS version AC_DEFUN([MBEDTLS_VERSION], m4_esyscmd_s(cd "others/mbedtls" && git describe && cd ../..)) # SecLang test version AC_DEFUN([SECLANG_TEST_VERSION], m4_esyscmd_s(cd "test/test-cases/secrules-language-tests" && git log -1 --format="%h" --abbrev-commit && cd ../../..)) # Check for yajl PROG_YAJL AM_CONDITIONAL([YAJL_VERSION], [test "$YAJL_VERSION" != ""]) # Check for LibGeoIP PROG_GEOIP # Check for MaxMind PROG_MAXMIND # Check for LMDB PROG_LMDB # Check for SSDEEP CHECK_SSDEEP # Check for LUA CHECK_LUA # # Check for curl # CHECK_CURL if ! test -z "${CURL_VERSION}"; then AC_DEFINE([MSC_WITH_CURL], [1], [Define if libcurl is available]) fi # # Check for LibXML # CHECK_LIBXML2 # # Check for libpcre only if explicitly requested # if test "x${with_pcre}" != "x" && test "x${with_pcre}" != "xno"; then CHECK_PCRE else # # Check for pcre2 # PROG_PCRE2 fi # Checks for header files. AC_CHECK_HEADERS([string]) AC_CHECK_HEADERS([iostream]) AC_CHECK_HEADERS([sys/utsname.h]) AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h libintl.h malloc.h netdb.h netinet/in.h stdint.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_CHECK_HEADER_STDBOOL AC_C_INLINE AC_TYPE_INT16_T AC_TYPE_INT32_T AC_TYPE_INT64_T AC_TYPE_INT8_T AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_TYPE_SSIZE_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_UINT8_T AC_CHECK_TYPES([ptrdiff_t]) AC_CHECK_TYPES([time_t]) # Checks for library functions. AC_FUNC_ERROR_AT_LINE AC_FUNC_FORK AC_FUNC_MALLOC AC_FUNC_REALLOC AC_CHECK_FUNCS([alarm clock_gettime gethostname gettimeofday inet_ntoa localtime_r memmove memset mkdir select setenv socket strcasecmp strchr strdup strerror strncasecmp strspn strstr strtol strtoul strtoull uname]) # Initialize libtool LT_INIT # Identify platform AC_CANONICAL_HOST case $host in *-*-aix*) echo "Checking platform... Identified as AIX" AC_DEFINE([AIX], [1], [Define if the operating system is AIX]) PLATFORM="AIX" ;; *-*-hpux*) echo "Checking platform... Identified as HPUX" AC_DEFINE([HPUX], [1], [Define if the operating system is HPUX]) PLATFORM="HPUX" ;; *-*-darwin*) echo "Checking platform... Identified as Macintosh OS X" AC_DEFINE([MACOSX], [1], [Define if the operating system is Macintosh OSX]) PLATFORM="MacOSX" ;; *-*-linux* | *-*uclinux*) echo "Checking platform... Identified as Linux" AC_DEFINE([LINUX], [1], [Define if the operating system is LINUX]) PLATFORM="Linux" ;; *-*-solaris*) echo "Checking platform... Identified as Solaris" AC_DEFINE([SOLARIS], [1], [Define if the operating system is SOLARIS]) PLATFORM="Solaris" ;; *-*-freebsd*) echo "Checking platform... Identified as FreeBSD" AC_DEFINE([FREEBSD], [1], [Define if the operating system is FREEBSD]) PLATFORM="FreeBSD" ;; *-*-netbsd*) echo "Checking platform... Identified as NetBSD" AC_DEFINE([NETBSD], [1], [Define if the operating system is NETBSD]) PLATFORM="NetBSD" ;; *-*-openbsd*) echo "Checking platform... Identified as OpenBSD" AC_DEFINE([OPENBSD], [1], [Define if the operating system is OPENBSD]) PLATFORM="OpenBSD" ;; *-*-kfreebsd*) echo "Checking platform... Identified as kFreeBSD, treating as linux" AC_DEFINE([FREEBSD], [1], [Define if the operating system is FREEBSD]) PLATFORM="kFreeBSD" ;; *-*-dragonfly*) echo "Checking platform... Identified as DragonFlyBSD, treating as linux" AC_DEFINE([DRAGONFLY], [1], [Define if the operating system is DRAGONFLY]) PLATFORM="DragonFly" ;; *-*-gnu*.*) echo "Checking platform... Identified as HURD, treating as linux" AC_DEFINE([LINUX], [1], [Define if the operating system is LINUX]) PLATFORM="HURD" ;; *) echo "Unknown CANONICAL_HOST $host" exit 1 ;; esac # Variables to be used inside the Makefile.am files. MSC_BASE_DIR=`pwd` AC_SUBST([MSC_BASE_DIR]) MSC_VERSION_INFO=msc_version_info AC_SUBST([MSC_VERSION_INFO]) MSC_VERSION_WITH_PATCHLEVEL=msc_version_with_patchlevel AC_SUBST([MSC_VERSION_WITH_PATCHLEVEL]) MSC_VERSION=msc_version AC_SUBST([MSC_VERSION]) MSC_GIT_VERSION=msc_version_git AC_SUBST([MSC_GIT_VERSION]) MSC_ARG_ENABLE_BOOL([assertions], [Turn on assertions feature: undefine NDEBUG], [false], [assertions]) MSC_ARG_ENABLE_BOOL([debug-logs], [Turn off the SecDebugLog feature], [true], [debugLogs]) if test "$debugLogs" != "true"; then MODSEC_NO_LOGS="-DNO_LOGS=1" AC_SUBST(MODSEC_NO_LOGS) fi MSC_ARG_ENABLE_BOOL([afl-fuzz], [Turn on the afl fuzzer compilation utilities], [false], [aflFuzzer]) MSC_ARG_ENABLE_BOOL([examples], [Turn on the examples compilation (default option)], [true], [buildExamples]) MSC_ARG_ENABLE_BOOL([parser-generation], [Enables parser generation during the build], [false], [buildParser]) MSC_ARG_ENABLE_BOOL([mutex-on-pm], [Treat pm operations as critical section], [false], [mutexPm]) if test $buildParser = true; then AC_PROG_YACC AC_PROG_LEX(noyywrap) AC_PATH_PROG([FLEX], [flex]) test "x$FLEX" = "x" && AC_MSG_ERROR([flex is needed to build ModSecurity]) AC_PATH_PROG([BISON], [bison]) test "x$BISON" = "x" && AC_MSG_ERROR([bison is needed to build ModSecurity]) AC_PATH_PROG([YACC_INST], $YACC) if test ! -f "$srcdir/gram.c"; then if test -z "$YACC_INST"; then AC_MSG_ERROR([yacc not found - unable to compile ModSecurity]) fi fi fi # Decide if we want to build the tests or not. buildTestUtilities=false if test "x$YAJL_FOUND" = "x1"; then # Regression tests will not be able to run without the logging support. # But we still have the unit tests. # if test "$debugLogs" = "true"; then buildTestUtilities=true # fi fi AM_CONDITIONAL([TEST_UTILITIES], [test $buildTestUtilities = true]) if test $buildTestUtilities = true; then if test $debugLogs = true; then if test -f ./test/test-list.sh; then TEST_CASES=`./test/test-list.sh` fi fi fi AM_CONDITIONAL([EXAMPLES], [test $buildExamples = true]) AM_CONDITIONAL([BUILD_PARSER], [test $buildParser = true]) AM_CONDITIONAL([USE_MUTEX_ON_PM], [test $mutexPm = true]) # General link options if test "$PLATFORM" != "MacOSX" -a "$PLATFORM" != "OpenBSD"; then GLOBAL_LDADD="-lrt " fi if test "$aflFuzzer" == "true"; then FUZZ_CPPCFLAGS="-fsanitize=address -fsanitize-coverage=4 " GLOBAL_LDADD="$GLOBAL_LDADD -fsanitize=address " GLOBAL_CPPFLAGS="$GLOBAL_CPPFLAGS $FUZZ_CPPCFLAGS" $buildExamples = false fi case $assertions in false) ASSERTIONS_CPPCFLAGS="-DNDEBUG" ;; true) ASSERTIONS_CPPCFLAGS="-UNDEBUG" ;; *) AC_MSG_ERROR(bad value ${assertions} for assertions) ;; esac GLOBAL_CPPFLAGS="$GLOBAL_CPPFLAGS $ASSERTIONS_CPPCFLAGS" AC_SUBST(GLOBAL_LDADD) AC_SUBST(GLOBAL_CPPFLAGS) AM_CONDITIONAL([AFL_FUZZER], [test $aflFuzzer = true]) GLOBAL_CFLAGS="" AC_SUBST(GLOBAL_CFLAGS) # Files to be generated via autotools. AC_CONFIG_FILES([\ modsecurity.pc \ Makefile \ doc/Makefile \ src/Makefile \ others/Makefile \ tools/Makefile \ tools/rules-check/Makefile ]) AM_COND_IF([TEST_UTILITIES], [AC_CONFIG_FILES([test/Makefile test/benchmark/Makefile])]) AM_COND_IF([EXAMPLES], [AC_CONFIG_FILES([ \ examples/Makefile \ examples/simple_example_using_c/Makefile \ examples/multiprocess_c/Makefile \ examples/multithread/Makefile \ examples/reading_logs_with_offset/Makefile \ examples/reading_logs_via_rule_message/Makefile \ examples/using_bodies_in_chunks/Makefile \ ])]) AM_COND_IF([AFL_FUZZER], [AC_CONFIG_FILES([test/fuzzer/Makefile])]) AM_COND_IF([BUILD_PARSER], [AC_CONFIG_FILES([src/parser/Makefile])]) AC_CONFIG_HEADERS([src/config.h]) # Doxygen support DX_HTML_FEATURE(ON) DX_CHM_FEATURE(OFF) DX_CHI_FEATURE(OFF) DX_MAN_FEATURE(OFF) DX_RTF_FEATURE(OFF) DX_XML_FEATURE(OFF) DX_PDF_FEATURE(OFF) DX_PS_FEATURE(OFF) DX_INIT_DOXYGEN([ModSecurity],[doc/doxygen.cfg]) # make check-valgrind AX_VALGRIND_DFLT([sgcheck], [off]) AX_VALGRIND_CHECK # Generate the files. AC_OUTPUT # Print a fancy summary echo " " echo " " echo "ModSecurity - ${MSC_GIT_VERSION} for $PLATFORM" echo " " echo " Mandatory dependencies" AS_ECHO_N(" + libInjection ....") echo LIBINJECTION_VERSION AS_ECHO_N(" + Mbed TLS ....") echo MBEDTLS_VERSION AS_ECHO_N(" + SecLang tests ....") echo SECLANG_TEST_VERSION echo " " echo " Optional dependencies" ## GeoIP - MaxMind (combined display) if test "x$GEOIP_FOUND" = "x0" && test "x$MAXMIND_FOUND" = "x0"; then echo " + GeoIP/MaxMind ....not found" fi if test "x$GEOIP_FOUND" = "x1" || test "x$MAXMIND_FOUND" = "x1"; then AS_ECHO_N([" + GeoIP/MaxMind ....found "]) echo "" if test "x$MAXMIND_FOUND" = "x1"; then echo " * (MaxMind) v${MAXMIND_VERSION}" echo " ${MAXMIND_DISPLAY}" fi if test "x$GEOIP_FOUND" = "x1"; then echo " * (GeoIP) v${GEOIP_VERSION}" echo " ${GEOIP_DISPLAY}" fi fi if test "x$GEOIP_FOUND" = "x2" && test "x$MAXMIND_FOUND" = "x2"; then echo " + GeoIP/MaxMind ....disabled" fi MSC_STATUS_LIB([LibCURL ], [CURL]) MSC_STATUS_LIB([YAJL ], [YAJL]) MSC_STATUS_LIB([LMDB ], [LMDB]) MSC_STATUS_LIB([LibXML2 ], [LIBXML2]) MSC_STATUS_LIB([SSDEEP ], [SSDEEP]) MSC_STATUS_LIB([LUA ], [LUA]) ## PCRE (only shown when explicitly requested) if test "x${with_pcre}" != "x" && test "x${with_pcre}" != "xno"; then if test -n "${PCRE_VERSION}"; then echo " + PCRE ....found " echo " using pcre v${PCRE_VERSION}" echo " ${PCRE_LDADD}, ${PCRE_CFLAGS}" else AC_MSG_NOTICE([*** pcre library not found.]) fi fi MSC_STATUS_LIB([PCRE2 ], [PCRE2]) echo " " echo " Other Options" if test $buildTestUtilities = true; then if test $debugLogs = true; then echo " + Test Utilities ....enabled" else echo " + Test Utilities ....partially" fi else echo " + Test Utilities ....disabled" fi if test $assertions = true; then echo " + Assertions ....enabled" else echo " + Assertions ....disabled" fi if test $debugLogs = true; then echo " + SecDebugLog ....enabled" else echo " + SecDebugLog ....disabled" fi if test "$aflFuzzer" = "true"; then echo " + afl fuzzer ....enabled" echo " ($FUZZ_CPPCFLAGS)" else echo " + afl fuzzer ....disabled" fi if test "$buildExamples" = "true"; then echo " + library examples ....enabled" else echo " + library examples ....disabled" fi if test "$buildParser" = "true"; then echo " + Building parser ....enabled" else echo " + Building parser ....disabled" fi if test "$mutexPm" = "true"; then echo " + Treating pm operations as critical section ....enabled" else echo " + Treating pm operations as critical section ....disabled" fi echo " " if test "$aflFuzzer" = "true"; then echo "WARNING: afl fuzzer was enabled. Make sure you are using the" echo " 'afl-clang-fast' as the compiler, otherwise the compilation" echo " will fail." echo " " echo " You can set the compiler using:" echo " " echo " $ export CXX=afl-clang-fast++ " echo " $ export CC=afl-clang-fast " echo " " fi ================================================ FILE: doc/.empty ================================================ ================================================ FILE: doc/Makefile.am ================================================ ACLOCAL_AMFLAGS = -I build # Doxygen support # include $(top_srcdir)/build/ax_prog_doxygen.m4 # distribution of the Doxygen configuration file EXTRA_DIST = \ doxygen.cfg MAINTAINERCLEANFILES = \ Makefile.in \ doxygen_sqlite3.db \ html \ latex ================================================ FILE: doc/doxygen.cfg ================================================ # Doxyfile 1.8.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = ModSecurity # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = 3.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "ModSecurity is an open source, cross platform web application firewall (WAF) engine for Apache, IIS and Nginx that is developed by Trustwave's SpiderLabs. It has a robust event-based programming language which provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring, logging and real-time analys…" # With the PROJECT_LOGO tag one can specify an logo or icon that is included in # the documentation. The maximum height of the logo should not exceed 55 pixels # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo # to the output directory. PROJECT_LOGO = ../doc/ms-doxygen-logo.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = ../doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = NO # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a # new page for each member. If set to NO, the documentation of a member will be # part of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # Fortran. In the later case the parser tries to guess whether the code is fixed # or free formatted code, this is the default for Fortran type files), VHDL. For # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined # locally in source files will be included in the documentation. If set to NO # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO these classes will be included in the various overviews. This option has # no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the # todo list. This list is created by putting \todo commands in the # documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the # test list. This list is created by putting \test commands in the # documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES the list # will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO doxygen will only warn about wrong or incomplete parameter # documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. # Note: If this tag is empty the current directory is searched. INPUT = ../headers/modsecurity/modsecurity.h ../src ../headers # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank the # following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, # *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.idl \ *.ddl \ *.odl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.cs \ *.d \ *.php \ *.php4 \ *.php5 \ *.phtml \ *.inc \ *.m \ *.markdown \ *.md \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.for \ *.tcl \ *.vhd \ *.vhdl \ *.ucf \ *.qsf \ *.as \ *.js # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER ) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES, then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the # clang parser (see: http://clang.llvm.org/) for more accurate parsing at the # cost of reduced performance. This can be particularly helpful with template # rich C++ code for which doxygen's built-in parser lacks the necessary type # information. # Note: The availability of this option depends on whether or not doxygen was # compiled with the --with-libclang option. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_OPTIONS = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefor more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra stylesheet files is of importance (e.g. the last # stylesheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the stylesheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to NO can help when comparing the output of multiple runs. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler ( hhc.exe). If non-empty # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated ( # YES) or that it should be included in the master .chm file ( NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated ( # YES) or a normal table of contents ( NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using prerendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /