55// (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
66#include <SAPI.h>
77#include <Zend/zend_extensions.h>
8+ #include <Zend/zend_operators.h>
9+ #include <Zend/zend_string.h>
10+ #include <Zend/zend_types.h>
811#include <ext/standard/info.h>
12+ #include <json/json.h>
913#include <php.h>
1014
1115// for open(2)
3741#include "php_objects.h"
3842#include "request_abort.h"
3943#include "request_lifecycle.h"
44+ #include "string_helpers.h"
4045#include "tags.h"
4146#include "telemetry.h"
4247#include "user_tracking.h"
4348#include "version.h"
4449
45- #include <json/json.h>
46- #include <zend_string.h>
47-
4850#if ZTS
4951static atomic_int _thread_count ;
5052#endif
@@ -468,8 +470,12 @@ static PHP_FUNCTION(datadog_appsec_testing_stop_for_debugger)
468470
469471static PHP_FUNCTION (datadog_appsec_testing_request_exec )
470472{
471- zval * data = NULL ;
472- if (zend_parse_parameters (ZEND_NUM_ARGS (), "z" , & data ) != SUCCESS ) {
473+ zend_array * data ;
474+ zend_string * rasp_rule = NULL ;
475+ zend_string * subctx_id = NULL ;
476+ bool subctx_last_call = false;
477+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "h|SSb" , & data , & rasp_rule ,
478+ & subctx_id , & subctx_last_call ) != SUCCESS ) {
473479 RETURN_FALSE ;
474480 }
475481
@@ -483,7 +489,13 @@ static PHP_FUNCTION(datadog_appsec_testing_request_exec)
483489 RETURN_FALSE ;
484490 }
485491
486- if (dd_request_exec (conn , data , false) != dd_success ) {
492+ struct req_exec_opts opts = {
493+ .rasp_rule = rasp_rule ,
494+ .subctx_id = subctx_id ,
495+ .subctx_last_call = subctx_last_call ,
496+ };
497+
498+ if (dd_request_exec (conn , data , & opts ) != dd_success ) {
487499 RETURN_FALSE ;
488500 }
489501
@@ -503,18 +515,64 @@ static PHP_FUNCTION(datadog_appsec_push_addresses)
503515 return ;
504516 }
505517
506- zval * addresses = NULL ;
507- zend_string * rasp_rule = NULL ;
508- if (zend_parse_parameters (ZEND_NUM_ARGS (), "z|S " , & addresses , & rasp_rule ) ==
518+ zend_array * addresses = NULL ;
519+ zval * opts_zv = NULL ;
520+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "h|z! " , & addresses , & opts_zv ) ==
509521 FAILURE ) {
510522 RETURN_FALSE ;
511523 }
512524
513- if (Z_TYPE_P (addresses ) != IS_ARRAY ) {
514- RETURN_FALSE ;
525+ if (opts_zv ) {
526+ ZVAL_DEREF (opts_zv );
527+ }
528+
529+ struct req_exec_opts opts = {0 };
530+ if (opts_zv && Z_TYPE_P (opts_zv ) == IS_ARRAY ) {
531+ zval * rasp_rule_zv =
532+ zend_hash_str_find (Z_ARR_P (opts_zv ), LSTRARG ("rasp_rule" ));
533+ if (rasp_rule_zv ) {
534+ ZVAL_DEREF (rasp_rule_zv );
535+ if (Z_TYPE_P (rasp_rule_zv ) != IS_STRING ) {
536+ php_error_docref (
537+ NULL , E_WARNING , "Invalid type for option rasp_rule" );
538+ RETURN_FALSE ;
539+ }
540+ opts .rasp_rule = Z_STR_P (rasp_rule_zv );
541+ }
542+
543+ zval * subctx_id_zv =
544+ zend_hash_str_find (Z_ARR_P (opts_zv ), LSTRARG ("subctx_id" ));
545+ if (subctx_id_zv ) {
546+ ZVAL_DEREF (subctx_id_zv );
547+ if (Z_TYPE_P (subctx_id_zv ) != IS_STRING ) {
548+ php_error_docref (
549+ NULL , E_WARNING , "Invalid type for option subctx_id" );
550+ RETURN_FALSE ;
551+ }
552+ opts .subctx_id = Z_STR_P (subctx_id_zv );
553+ }
554+
555+ zval * subctx_last_call_zv =
556+ zend_hash_str_find (Z_ARR_P (opts_zv ), LSTRARG ("subctx_last_call" ));
557+ if (subctx_last_call_zv ) {
558+ ZVAL_DEREF (subctx_last_call_zv );
559+ if (Z_TYPE_P (subctx_last_call_zv ) != IS_TRUE &&
560+ Z_TYPE_P (subctx_last_call_zv ) != IS_FALSE ) {
561+ php_error_docref (NULL , E_WARNING ,
562+ "Invalid type for option subctx_last_call" );
563+ RETURN_FALSE ;
564+ }
565+ opts .subctx_last_call = Z_TYPE_P (subctx_last_call_zv ) == IS_TRUE ;
566+ }
567+ } else if (opts_zv ) {
568+ // legacy second string argument
569+ if (!try_convert_to_string (opts_zv )) {
570+ RETURN_FALSE ;
571+ }
572+ opts .rasp_rule = Z_STR_P (opts_zv );
515573 }
516574
517- if (rasp_rule && ZSTR_LEN (rasp_rule ) > 0 &&
575+ if (opts . rasp_rule && ZSTR_LEN (opts . rasp_rule ) > 0 &&
518576 !get_global_DD_APPSEC_RASP_ENABLED ()) {
519577 return ;
520578 }
@@ -525,9 +583,9 @@ static PHP_FUNCTION(datadog_appsec_push_addresses)
525583 return ;
526584 }
527585
528- dd_result res = dd_request_exec (conn , addresses , rasp_rule );
586+ dd_result res = dd_request_exec (conn , addresses , & opts );
529587
530- if (rasp_rule && ZSTR_LEN (rasp_rule ) > 0 ) {
588+ if (opts . rasp_rule && ZSTR_LEN (opts . rasp_rule ) > 0 ) {
531589 clock_gettime (CLOCK_MONOTONIC_RAW , & end );
532590 elapsed =
533591 ((int64_t )end .tv_sec - (int64_t )start .tv_sec ) *
@@ -559,12 +617,15 @@ ZEND_END_ARG_INFO()
559617
560618ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX (request_exec_arginfo , 0 , 1 , _IS_BOOL , 0 )
561619ZEND_ARG_INFO (0 , "data" )
620+ ZEND_ARG_INFO_WITH_DEFAULT_VALUE (0 , "rasp_rule" , NULL )
621+ ZEND_ARG_INFO_WITH_DEFAULT_VALUE (0 , "subctx_id" , NULL )
622+ ZEND_ARG_INFO_WITH_DEFAULT_VALUE (0 , "subctx_last_call" , false)
562623ZEND_END_ARG_INFO ()
563624
564625ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX (
565626 push_addresses_arginfo , 0 , 0 , IS_VOID , 1 )
566627ZEND_ARG_INFO (0 , addresses )
567- ZEND_ARG_INFO (0 , rasp )
628+ ZEND_ARG_INFO_WITH_DEFAULT_VALUE (0 , rasp_rule_or_opts , NULL )
568629ZEND_END_ARG_INFO ()
569630
570631// clang-format off
0 commit comments