1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
// Unless explicitly stated otherwise all files in this repository are
// dual-licensed under the Apache-2.0 License or BSD-3-Clause License.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2021 Datadog, Inc.
#ifndef DDWAF_H
#define DDWAF_H
#ifdef __cplusplus
#include <cstddef>
namespace ddwaf{
class waf;
class context;
class subcontext;
class waf_builder;
} // namespace ddwaf
using ddwaf_handle = ddwaf::waf *;
using ddwaf_context = ddwaf::context *;
using ddwaf_subcontext = ddwaf::subcontext *;
using ddwaf_builder = ddwaf::waf_builder *;
using ddwaf_allocator = void *;
using ddwaf_alloc_fn_type = void *(*)(void *, size_t, size_t);
using ddwaf_free_fn_type = void (*)(void *, void *, size_t, size_t);
using ddwaf_udata_free_fn_type = void (*)(void *);
extern "C"
{
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/**
* @enum DDWAF_OBJ_TYPE
*
* Specifies the type of a ddwaf::object.
**/
typedef enum
{
/** Unkmown or uninitialised type **/
DDWAF_OBJ_INVALID = 0,
/** Null type, only used for its semantical value **/
DDWAF_OBJ_NULL = 0x01,
/** Boolean type **/
DDWAF_OBJ_BOOL = 0x02,
/** 64-bit signed integer type **/
DDWAF_OBJ_SIGNED = 0x04,
/** 64-bit unsigned integer type **/
DDWAF_OBJ_UNSIGNED = 0x06,
/** 64-bit float (or double) type **/
DDWAF_OBJ_FLOAT = 0x08,
/** Dynamic UTF-8 string of up to max(uint32) length **/
DDWAF_OBJ_STRING = 0x10,
/** Literal UTF-8 string of up to max(uint32) length, these are never freed **/
DDWAF_OBJ_LITERAL_STRING = 0x12,
/** UTF-8 string of up to 14 bytes in length **/
DDWAF_OBJ_SMALL_STRING = 0x14,
/** Array of ddwaf_object, up to max(uint16) capacity **/
DDWAF_OBJ_ARRAY = 0x20,
/** Array of ddwaf_object_kv, up to max(uint16) capacity **/
DDWAF_OBJ_MAP = 0x40,
/** Array of ddwaf_object with up to 28-bit capacity **/
DDWAF_OBJ_LARGE_ARRAY = 0xA0,
/** Array of ddwaf_object_kv with up to 28-bit capacity **/
DDWAF_OBJ_LARGE_MAP = 0xC0,
} DDWAF_OBJ_TYPE;
/**
* @enum DDWAF_RET_CODE
*
* Codes returned by ddwaf_context_eval.
**/
typedef enum
{
/** Unknown error, typically due to an unexpected exception **/
DDWAF_ERR_INTERNAL = -3,
/** The provided data object didn't match the expected schema **/
DDWAF_ERR_INVALID_OBJECT = -2,
/** One or more of the provided arguments to a function is invalid **/
DDWAF_ERR_INVALID_ARGUMENT = -1,
/** The data evaluation didn't yield any events, attributes, etc **/
DDWAF_OK = 0,
/** The data evaluation resulted in an event, attribute, etc **/
DDWAF_MATCH = 1,
} DDWAF_RET_CODE;
/**
* @enum DDWAF_LOG_LEVEL
*
* Internal WAF log levels, to be used when setting the minimum log level and cb.
**/
typedef enum
{
/** Finest-grained logging for detailed tracing */
DDWAF_LOG_TRACE = 0,
/** Debugging information for development */
DDWAF_LOG_DEBUG = 1,
/** General informational messages */
DDWAF_LOG_INFO = 2,
/** Warning messages for potential issues */
DDWAF_LOG_WARN = 3,
/** Error messages for failures */
DDWAF_LOG_ERROR = 4,
/** Disable all logging */
DDWAF_LOG_OFF = 5,
} DDWAF_LOG_LEVEL;
#ifndef __cplusplus
typedef struct _ddwaf_handle* ddwaf_handle;
typedef struct _ddwaf_context* ddwaf_context;
typedef struct _ddwaf_subcontext* ddwaf_subcontext;
typedef struct _ddwaf_builder* ddwaf_builder;
typedef struct _ddwaf_allocator* ddwaf_allocator;
typedef void *(ddwaf_alloc_fn_type)(void *, size_t, size_t);
typedef void (ddwaf_free_fn_type)(void *, void *, size_t, size_t);
typedef void (ddwaf_udata_free_fn_type)(void *);
#endif
typedef union _ddwaf_object ddwaf_object;
typedef struct _ddwaf_object_kv ddwaf_object_kv;
struct _ddwaf_object_bool {
uint8_t type;
bool val;
};
struct _ddwaf_object_signed {
uint8_t type;
int64_t val;
};
struct _ddwaf_object_unsigned {
uint8_t type;
uint64_t val;
};
struct _ddwaf_object_float {
uint8_t type;
double val;
};
struct _ddwaf_object_string {
uint8_t type;
uint32_t size;
char *ptr;
};
struct _ddwaf_object_small_string {
#define DDWAF_OBJ_SSTR_SIZE 14
uint8_t type;
uint8_t size;
char data[DDWAF_OBJ_SSTR_SIZE];
};
struct _ddwaf_object_array {
uint8_t type;
uint16_t size;
uint16_t capacity;
union _ddwaf_object *ptr;
};
struct _ddwaf_object_map {
uint8_t type;
uint16_t size;
uint16_t capacity;
struct _ddwaf_object_kv *ptr;
};
struct _ddwaf_object_large_array {
uint64_t _type : 8;
uint64_t size : 28;
uint64_t capacity : 28;
union _ddwaf_object *ptr;
};
struct _ddwaf_object_large_map {
uint64_t _type : 8;
uint64_t size : 28;
uint64_t capacity : 28;
struct _ddwaf_object_kv *ptr;
};
/**
* @struct ddwaf_object
*
* Generic object used to pass data and rules to the WAF.
**/
#ifdef _MSC_VER
union _ddwaf_object {
#else
union __attribute__((may_alias)) _ddwaf_object {
#endif
uint8_t type;
union {
struct _ddwaf_object_bool b8;
struct _ddwaf_object_signed i64;
struct _ddwaf_object_unsigned u64;
struct _ddwaf_object_float f64;
struct _ddwaf_object_string str;
struct _ddwaf_object_small_string sstr;
struct _ddwaf_object_array array;
struct _ddwaf_object_map map;
struct _ddwaf_object_large_array large_array;
struct _ddwaf_object_large_map large_map;
} via;
};
struct _ddwaf_object_kv {
union _ddwaf_object key;
union _ddwaf_object val;
};
/**
* @typedef ddwaf_log_cb
*
* Callback that libddwaf will call to relay messages to the binding.
*
* @param level The logging level.
* @param function The native function that emitted the message. (nonnull)
* @param file The file of the native function that emmitted the message. (nonnull)
* @param line The line where the message was emmitted.
* @param message The size of the logging message. NUL-terminated
* @param message_len The length of the logging message (excluding NUL terminator).
*/
typedef void (*ddwaf_log_cb)(
DDWAF_LOG_LEVEL level, const char* function, const char* file, unsigned line,
const char* message, uint64_t message_len);
/**
* Initialize a ddwaf instance
*
* @param ruleset ddwaf::object map containing rules, exclusions, rules_override and rules_data. (nonnull)
* @param diagnostics Optional ruleset parsing diagnostics. (nullable)
*
* @return Handle to the WAF instance or NULL on error.
*
* @note If ruleset is NULL, the diagnostics object will not be initialised.
*
* @note The deallocation of the diagnostics must be made with default allocator.
**/
ddwaf_handle ddwaf_init(const ddwaf_object *ruleset, ddwaf_object *diagnostics);
/**
* Destroy a WAF instance.
*
* @param handle Handle to the WAF instance.
*/
void ddwaf_destroy(ddwaf_handle handle);
/**
* Get an array of known (root) addresses used by rules, exclusion filters and
* processors. This array contains both required and optional addresses. A more
* accurate distinction between required and optional addresses is provided
* within the diagnostics.
*
* The memory is owned by the WAF and should not be freed.
*
* @param handle Handle to the WAF instance.
* @param size Output parameter in which the size will be returned. The value of
* size will be 0 if the return value is NULL.
* @return NULL if empty, otherwise a pointer to an array with size elements.
*
* @note This function is not thread-safe
* @note The returned array should be considered invalid after calling ddwaf_destroy
* on the handle used to obtain it.
**/
const char* const* ddwaf_known_addresses(const ddwaf_handle handle, uint32_t *size);
/**
* Get an array of all the action types which could be triggered as a result of
* the current set of rules and exclusion filters.
*
* The memory is owned by the WAF and should not be freed.
*
* @param handle Handle to the WAF instance.
* @param size Output parameter in which the size will be returned. The value of
* size will be 0 if the return value is NULL.
* @return NULL if empty, otherwise a pointer to an array with size elements.
*
* @note This function is not thread-safe
* @note The returned array should be considered invalid after calling ddwaf_destroy
* on the handle used to obtain it.
**/
const char *const *ddwaf_known_actions(const ddwaf_handle handle, uint32_t *size);
/**
* Context object to perform matching using the provided WAF instance.
*
* @param handle Handle of the WAF instance containing the ruleset definition. (nonnull)
* @param output_alloc Allocator used to serve output objects created during evaluation (nonnull)
* @return Handle to the context instance.
*
* @note The WAF instance needs to be valid for the lifetime of the context.
**/
ddwaf_context ddwaf_context_init(const ddwaf_handle handle, ddwaf_allocator output_alloc);
/**
* Perform a matching operation on the provided data
*
* @param context WAF context to be used in this run, this will determine the
* ruleset which will be used and it will also ensure that
* parameters are taken into account across runs (nonnull)
*
* @param data (nonnull) Data on which to perform the pattern matching. This
* data will be stored by the context and used across multiple calls to this
* function or ddwaf_subcontext_eval. Once the context is destroyed, the user
* defined allocator will be used to free the data provided. Note that the
* data passed must be valid until the destruction of the context. The object
* must be a map of {string, <value>} in which each key represents the
* relevant address associated to the value, which can be of an arbitrary
* type.
*
* @param alloc (nullable) Allocator used to free the data provided. If NULL,
* the data will not be freed.
*
* @param result (nullable) Object map containing the following items:
* - events: an array of the generated events.
* - actions: a map of the generated actions in the format:
* "{action type: { <parameter map> }, ...}"
* - duration: an unsigned specifying the total runtime of the
* call in nanoseconds.
* - timeout: whether there has been a timeout during the call.
* - attributes: a map containing all derived objects in the
* format: {tag, value}
* - keep: whether the data contained herein must override any
* transport sampling through the relevant mechanism.
* - evaluated: an unsigned integer indicating the number of input
* batches that were fully evaluated. For this single
* evaluation it is 1 once the batch has been
* evaluated, or 0 if a timeout prevented that. See
* ddwaf_context_multieval for the multi-batch case.
* This structure must be freed by the caller using the output
* allocator provided through ddwaf_context_init. The object will
* contain all specified keys when the value returned by
* ddwaf_context_eval is either DDWAF_OK or DDWAF_MATCH and will
* be empty otherwise.
* IMPORTANT: This object is not allocated with the allocator
* passed in this call. It uses the allocator given to
* ddwaf_context_init instead.
* @param timeout Maximum time budget in microseconds.
*
* @return Return code of the operation.
* @retval DDWAF_ERR_INVALID_ARGUMENT The context is invalid, the data will not
* be freed.
* @retval DDWAF_ERR_INVALID_OBJECT The data provided didn't match the desired
* structure or contained invalid objects, the
* data will be freed by this function.
* @retval DDWAF_ERR_INTERNAL There was an unexpected error and the operation did
* not succeed. The state of the WAF is undefined if
* this error is produced and the ownership of the
* data is unknown. The result structure will not be
* filled if this error occurs.
*
* Notes on addresses:
* - Within a single run, addresses provided should be unique.
* If duplicate addresses are provided:
* - Within the same batch, the latest one in the structure will be the one
* used for evaluation.
* - Within two different batches, the second batch will only use the new data.
**/
DDWAF_RET_CODE ddwaf_context_eval(ddwaf_context context, ddwaf_object *data,
ddwaf_allocator alloc, ddwaf_object *result, uint64_t timeout);
/**
* Perform multiple matching operations on the provided data, evaluating each
* batch in sequence and returning a single combined result.
*
* This function operates identically to ddwaf_context_eval, with the
* distinction that data must be an array of maps. Each element is treated as
* a separate input batch and is evaluated in order. Addresses provided in
* earlier batches persist in the store and remain available when evaluating
* later batches, so a rule that requires multiple addresses can be satisfied
* by data spread across different batches within a single call. The result
* reflects all events, actions, and attributes accumulated across the entire
* sequence of batches.
*
* @param context WAF context to be used in this run, this will determine the
* ruleset which will be used and it will also ensure that
* parameters are taken into account across runs. (nonnull)
*
* @param data (nonnull) Array of input batches to evaluate. Each element must
* be a map of {string, <value>} where each key represents the relevant
* address associated to the value, which can be of an arbitrary type. The
* batches are evaluated in order. If the same address appears in multiple
* batches, the later value replaces the earlier one. Passing a non-array
* object will return DDWAF_ERR_INVALID_OBJECT.
* Ownership and lifetime semantics are identical to ddwaf_context_eval:
* the data is stored by the context and the provided allocator is used to
* free it once the context is destroyed.
*
* @param alloc (nullable) Allocator used to free the data provided. If NULL,
* the data will not be freed.
*
* @param result (nullable) Object map containing the following items:
* - events: an array of all events generated across all batches.
* - actions: a map of all actions generated across all batches
* in the format: "{action type: { <parameter map> }, ...}"
* - duration: an unsigned specifying the total runtime of the
* call in nanoseconds.
* - timeout: whether there has been a timeout during the call.
* - attributes: a map containing all derived objects in the
* format: {tag, value}
* - keep: whether the data contained herein must override any
* transport sampling through the relevant mechanism.
* - evaluated: an unsigned integer indicating the number of input
* batches that were fully evaluated. In the normal
* case this equals the total number of batches
* provided; it is lower when evaluation stops early,
* e.g. on a timeout or once a batch produces a
* blocking result. Empty batches are evaluated like
* any other and count towards this value.
* This structure must be freed by the caller using the output
* allocator provided through ddwaf_context_init. The object will
* contain all specified keys when the value returned by
* ddwaf_context_multieval is either DDWAF_OK or DDWAF_MATCH and
* will be empty otherwise.
* IMPORTANT: This object is not allocated with the allocator
* passed in this call. It uses the allocator given to
* ddwaf_context_init instead.
* @param timeout Maximum time budget in microseconds.
*
* @return Return code of the operation.
* @retval DDWAF_ERR_INVALID_ARGUMENT The context is invalid, the data will not
* be freed.
* @retval DDWAF_ERR_INVALID_OBJECT The data provided didn't match the desired
* structure or contained invalid objects, the
* data will be freed by this function.
* @retval DDWAF_ERR_INTERNAL There was an unexpected error and the operation did
* not succeed. The state of the WAF is undefined if
* this error is produced and the ownership of the
* data is unknown. The result structure will not be
* filled if this error occurs.
*
* Notes on addresses:
* - Within a single batch, addresses provided should be unique.
* If duplicate addresses are provided within the same batch, the latest one
* in the structure will be used for evaluation.
* - Addresses from earlier batches persist in the store and are accessible
* during evaluation of subsequent batches within the same call. If the same
* address appears in a later batch, the later value replaces the earlier one.
* - A rule that requires multiple addresses can be satisfied by data spread
* across different batches within a single call.
**/
DDWAF_RET_CODE ddwaf_context_multieval(ddwaf_context context, ddwaf_object *data,
ddwaf_allocator alloc, ddwaf_object *result, uint64_t timeout);
/**
* Performs the destruction of the context, freeing the data passed to it through
* ddwaf_context_eval using the provided allocator during evaluation.
*
* @param context Context to destroy. (nonnull)
**/
void ddwaf_context_destroy(ddwaf_context context);
/**
* Subcontext object to perform matching using the provided WAF instance.
*
* @param context Context from which to derive this subcontext. (nonnull)
* @return Handle to the subcontext instance.
**/
ddwaf_subcontext ddwaf_subcontext_init(ddwaf_context context);
/**
* Perform a matching operation on the provided data
*
* @param subcontext WAF subcontext to be used in this run, this will determine
* the ruleset which will be used and it will also ensure that parameters are
* taken into account across runs (nonnull)
*
* @param data (nonnull) Data on which to perform the pattern matching. This
* data will be stored by the subcontext and used across multiple calls to this
* function. Once the subcontext is destroyed, the user defined allocator will
* be used to free the data provided. Note that the data passed must be valid
* until the destruction of the subcontext. The object must be a map of
* {string, <value>} in which each key represents the relevant address
* associated to the value, which can be of an arbitrary type.
*
* @param alloc (nullable) Allocator used to free the data provided. If NULL,
* the data will not be freed.
*
* @param result (nullable) Object map containing the following items:
* - events: an array of the generated events.
* - actions: a map of the generated actions in the format:
* "{action type: { <parameter map> }, ...}"
* - duration: an unsigned specifying the total runtime of the
* call in nanoseconds.
* - timeout: whether there has been a timeout during the call.
* - attributes: a map containing all derived objects in the
* format: {tag, value}
* - keep: whether the data contained herein must override any
* transport sampling through the relevant mechanism.
* - evaluated: an unsigned integer indicating the number of input
* batches that were fully evaluated. For this single
* evaluation it is 1 once the batch has been
* evaluated, or 0 if a timeout prevented that. See
* ddwaf_subcontext_multieval for the multi-batch case.
* This structure must be freed by the caller and will contain all
* specified keys when the value returned by ddwaf_subcontext_eval
* is either DDWAF_OK or DDWAF_MATCH and will be empty otherwise.
* IMPORTANT: This object is not allocated with the allocator
* passed in this call. It uses the allocator given to
* ddwaf_context_init instead.
* @param timeout Maximum time budget in microseconds.
*
* @return Return code of the operation.
* @retval DDWAF_ERR_INVALID_ARGUMENT The subcontext is invalid, the data will not
* be freed.
* @retval DDWAF_ERR_INVALID_OBJECT The data provided didn't match the desired
* structure or contained invalid objects, the
* data will be freed by this function.
* @retval DDWAF_ERR_INTERNAL There was an unexpected error and the operation did
* not succeed. The state of the WAF is undefined if
* this error is produced and the ownership of the
* data is unknown. The result structure will not be
* filled if this error occurs.
*
* Notes on addresses:
* - Within a single run, addresses provided should be unique.
* If duplicate addresses are provided:
* - Within the same batch, the latest one in the structure will be the one
* used for evaluation.
* - Within two different batches, the second batch will only use the new data.
**/
DDWAF_RET_CODE ddwaf_subcontext_eval(ddwaf_subcontext subcontext, ddwaf_object *data,
ddwaf_allocator alloc, ddwaf_object *result, uint64_t timeout);
/**
* Perform multiple matching operations on the provided data, evaluating each
* batch in sequence and returning a single combined result.
*
* This function operates identically to ddwaf_subcontext_eval, with the
* distinction that data must be an array of maps. Each element is treated as
* a separate input batch and is evaluated in order. Addresses provided in
* earlier batches persist in the store and remain available when evaluating
* later batches, so a rule that requires multiple addresses can be satisfied
* by data spread across different batches within a single call. The result
* reflects all events, actions, and attributes accumulated across the entire
* sequence of batches.
*
* @param subcontext WAF subcontext to be used in this run, this will determine
* the ruleset which will be used and it will also ensure that
* parameters are taken into account across runs. (nonnull)
*
* @param data (nonnull) Array of input batches to evaluate. Each element must
* be a map of {string, <value>} where each key represents the relevant
* address associated to the value, which can be of an arbitrary type. The
* batches are evaluated in order. If the same address appears in multiple
* batches, the later value replaces the earlier one. Passing a non-array
* object will return DDWAF_ERR_INVALID_OBJECT.
* Ownership and lifetime semantics are identical to ddwaf_subcontext_eval:
* the data is stored by the subcontext and the provided allocator is used
* to free it once the subcontext is destroyed.
*
* @param alloc (nullable) Allocator used to free the data provided. If NULL,
* the data will not be freed.
*
* @param result (nullable) Object map containing the following items:
* - events: an array of all events generated across all batches.
* - actions: a map of all actions generated across all batches
* in the format: "{action type: { <parameter map> }, ...}"
* - duration: an unsigned specifying the total runtime of the
* call in nanoseconds.
* - timeout: whether there has been a timeout during the call.
* - attributes: a map containing all derived objects in the
* format: {tag, value}
* - keep: whether the data contained herein must override any
* transport sampling through the relevant mechanism.
* - evaluated: an unsigned integer indicating the number of input
* batches that were fully evaluated. In the normal
* case this equals the total number of batches
* provided; it is lower when evaluation stops early,
* e.g. on a timeout or once a batch produces a
* blocking result. Empty batches are evaluated like
* any other and count towards this value.
* This structure must be freed by the caller and will contain all
* specified keys when the value returned by
* ddwaf_subcontext_multieval is either DDWAF_OK or DDWAF_MATCH
* and will be empty otherwise.
* IMPORTANT: This object is not allocated with the allocator
* passed in this call. It uses the allocator given to
* ddwaf_context_init instead.
* @param timeout Maximum time budget in microseconds.
*
* @return Return code of the operation.
* @retval DDWAF_ERR_INVALID_ARGUMENT The subcontext is invalid, the data will
* not be freed.
* @retval DDWAF_ERR_INVALID_OBJECT The data provided didn't match the desired
* structure or contained invalid objects, the
* data will be freed by this function.
* @retval DDWAF_ERR_INTERNAL There was an unexpected error and the operation did
* not succeed. The state of the WAF is undefined if
* this error is produced and the ownership of the
* data is unknown. The result structure will not be
* filled if this error occurs.
*
* Notes on addresses:
* - Within a single batch, addresses provided should be unique.
* If duplicate addresses are provided within the same batch, the latest one
* in the structure will be used for evaluation.
* - Addresses from earlier batches persist in the store and are accessible
* during evaluation of subsequent batches within the same call. If the same
* address appears in a later batch, the later value replaces the earlier one.
* - A rule that requires multiple addresses can be satisfied by data spread
* across different batches within a single call.
**/
DDWAF_RET_CODE ddwaf_subcontext_multieval(ddwaf_subcontext subcontext, ddwaf_object *data,
ddwaf_allocator alloc, ddwaf_object *result, uint64_t timeout);
/**
* Performs the destruction of the subcontext, freeing the data passed to it through
* ddwaf_subcontext_eval using the used-defined allocator.
*
* @param subcontext subcontext to destroy. (nonnull)
**/
void ddwaf_subcontext_destroy(ddwaf_subcontext subcontext);
/**
* Initialize an instace of the waf builder.
*
* @return Handle to the builer instance or NULL on error.
*
* @note If config is NULL, default values will be used
**/
ddwaf_builder ddwaf_builder_init();
/**
* Adds or updates a configuration based on the given path, which must be a unique
* identifier for the provided configuration.
*
* @param builder Builder to perform the operation on. (nonnull)
* @param path A string containing the path of the configuration, this must uniquely identify the configuration. (nonnull)
* @param path_len The length of the string contained within path.
* @param config ddwaf::object map containing rules, exclusions, rules_override and rules_data. (nonnull)
* @param diagnostics Optional ruleset parsing diagnostics. (nullable)
*
* @return Whether the operation succeeded (true) or failed (false).
*
* @note if any of the arguments are NULL, the diagnostics object will not be initialised.
* @note The memory associated with the path, config and diagnostics must be freed by the caller.
* @note The deallocation of the diagnostics must be made with default allocator.
* @note This function is not thread-safe.
**/
bool ddwaf_builder_add_or_update_config(ddwaf_builder builder, const char *path, uint32_t path_len, const ddwaf_object *config, ddwaf_object *diagnostics);
/**
* Removes a configuration based on the provided path.
*
* @param builder Builder to perform the operation on. (nonnull)
* @param path A string containing the path of the configuration to be removed. (nonnull)
* @param path_len The length of the string contained within path.
*
* @return Whether the operation succeeded (true) or failed (false).
*
* @note The memory associated with the path must be freed by the caller.
* @note This function is not thread-safe.
**/
bool ddwaf_builder_remove_config(ddwaf_builder builder, const char *path, uint32_t path_len);
/**
* Builds a ddwaf instance based on the current set of configurations.
*
* @param builder Builder to perform the operation on. (nonnull)
*
* @return Handle to the new WAF instance or NULL if there was an error.
*
* @note This function is not thread-safe.
**/
ddwaf_handle ddwaf_builder_build_instance(ddwaf_builder builder);
/**
* Provides an array of the currently loaded paths, optionally matching the
* regex provided in filter. In addition, the count is provided as the return
* value, allowing paths to be nullptr.
*
* @param builder Builder to perform the operation on. (nonnull)
* @param paths The object in which paths will be returned, as an array of
* strings. If NULL, only the count is provided. (nullable)
* @param filter An optional string regex to filter the provided paths. The
* provided regular expression is used unanchored so matches can be found
* at any point within the path, any necessary anchors must be explicitly
* added to the regex. (nullable).
* @param filter_len The length of the filter string (or 0 otherwise).
*
* @return The total number of configurations loaded or, if provided, the number
* of those matching the filter.
*
* @note This function is not thread-safe and the memory of the paths object must
* be freed by the caller using the default allocator.
**/
uint32_t ddwaf_builder_get_config_paths(ddwaf_builder builder, ddwaf_object *paths, const char *filter, uint32_t filter_len);
/**
* Destroy an instance of the builder.
*
* @param builder Builder to perform the operation on. (nonnull)
*/
void ddwaf_builder_destroy(ddwaf_builder builder);
/**
* Returns the default allocator used by the library.
*
* @return Allocator handle.
**/
ddwaf_allocator ddwaf_get_default_allocator();
/**
* Creates a thread-safe pool allocator. Allocations are served from internal
* pools sized by block class to reduce fragmentation and allocator overhead;
* memory freed via the corresponding ddwaf APIs is returned to the pools for
* reuse. This allocator can be shared across threads safely.
*
* Lifetime and safety:
* - The allocator must not be destroyed while any memory obtained from it is
* still in use; doing so will invalidate outstanding pointers.
*
* @return Allocator handle.
**/
ddwaf_allocator ddwaf_synchronized_pool_allocator_init();
/**
* Creates a pool allocator without internal synchronization. It provides the
* same pooling characteristics as the synchronized variant but with lower
* overhead. This allocator must not be used concurrently from multiple threads
* unless externally synchronized.
*
* Lifetime and safety:
* - The allocator must not be destroyed while any memory obtained from it is
* still in use; doing so will invalidate outstanding pointers.
*
* @return Allocator handle.
**/
ddwaf_allocator ddwaf_unsynchronized_pool_allocator_init();
/**
* Creates a monotonic (growing) allocator. Allocations are fast and never freed
* individually; all memory is reclaimed only when the allocator is destroyed.
* This allocator must not be used concurrently from multiple threads unless
* externally synchronized.
*
* Lifetime and safety:
* - Objects allocated from this allocator remain valid until the allocator is
* destroyed; individual frees have no effect.
* - The allocator must not be destroyed while any memory obtained from it is
* still in use; doing so will invalidate outstanding pointers.
*
* @return Allocator handle.
**/
ddwaf_allocator ddwaf_monotonic_allocator_init();
/**
* Creates an allocator that forwards allocation and deallocation to user
* provided callbacks.
*
* @param alloc_fn Allocation callback. It receives the opaque `udata`, the
* requested `size` and `alignment`, and must return a pointer meeting the
* alignment requirements or NULL on failure. (nonnull)
* @param free_fn Deallocation callback. It receives the opaque `udata`, the
* pointer to free, and the original `size` and `alignment`. It must be
* able to free any pointer previously returned by `alloc_fn`. (nonnull)
* @param udata Opaque user pointer forwarded to both callbacks; can be used to
* carry custom state. (nullable)
* @param udata_free_fn User data destruction callback, used to perform any
* relevant destruction and reclamation operations on the provided user
* data.
*
* @return Allocator handle.
**/
ddwaf_allocator ddwaf_user_allocator_init(ddwaf_alloc_fn_type alloc_fn, ddwaf_free_fn_type free_fn, void *udata, ddwaf_udata_free_fn_type udata_free_fn);
/**
* Allocates a block of memory from the given allocator with the requested
* alignment.
*
* Usage and guarantees:
* - The returned pointer is aligned to `alignment` bytes.
* - Returns NULL on allocation failure.
* - Memory obtained with this function must be released with
* ddwaf_allocator_free using the same allocator and the same `bytes` and
* `alignment` values.
* - Thread-safety depends on the allocator type; see the corresponding
* allocator init function for details.
*
* @param alloc Allocator to use for the allocation. (nonnull)
* @param bytes Number of bytes to allocate.
* @param alignment Required alignment in bytes; must be a power of two.
*
* @return Pointer to the allocated memory or NULL on failure.
**/
void *ddwaf_allocator_alloc(ddwaf_allocator alloc, size_t bytes, size_t alignment);
/**
* Releases a block of memory previously obtained via ddwaf_allocator_alloc
* from the same allocator.
*
* Requirements and safety:
* - `p` must point to memory returned by ddwaf_allocator_alloc using `alloc`.
* - `bytes` and `alignment` must match the values used for the allocation.
* - After this call, the memory referenced by `p` must no longer be accessed.
* - Do not mix allocators; freeing with a different allocator is undefined.
* - Thread-safety depends on the allocator type; see the corresponding
* allocator init function for details.
*
* @param alloc Allocator used for the original allocation. (nonnull)
* @param p Pointer to the memory to free. (nonnull)
* @param bytes Size in bytes of the original allocation.
* @param alignment Alignment in bytes of the original allocation.
**/
void ddwaf_allocator_free(ddwaf_allocator alloc, void *p, size_t bytes, size_t alignment);
/**
* Destroys an allocator created by one of the ddwaf_*_allocator_init functions
* and releases any internal resources it holds.
*
* Safety and lifetime:
* - It is the caller's responsibility to ensure no outstanding memory from the
* allocator is still in use at the time of destruction.
* - Must not called concurrently with other operations using the same allocator.
* - Attempting to destroy the default allocator is a no-op and has no ill-effects.
*
* @param alloc Allocator to destroy. (nonnull)
**/
void ddwaf_allocator_destroy(ddwaf_allocator alloc);
/**
* Creates an invalid object.
*
* @param object Object to perform the operation on. (nonnull)
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_invalid(ddwaf_object *object);
/**
* Creates an null object. Provides a different semantical value to invalid as
* it can be used to signify that a value is null rather than of an unknown type.
*
* @param object Object to perform the operation on. (nonnull)
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_null(ddwaf_object *object);
/**
* Creates an object from a string.
*
* @param object Object to perform the operation on. (nonnull)
* @param string String to initialise the object with, this string will be copied. (nonnull)
* @param length Length of the string.
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_string(ddwaf_object *object, const char *string, uint32_t length, ddwaf_allocator alloc);
/**
* Creates an object from a literal string and its length.
*
* @param object Object to perform the operation on. (nonnull)
* @param string Literal string to initialise the object with, this string will not be copied
* and must remain valid for the lifetime of the object. (nonnull)
* @param length Length of the string.
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_string_literal(ddwaf_object *object, const char *string, uint32_t length);
/**
* Creates an object with the string pointer and length provided, without copying the string.
*
* @param object Object to perform the operation on. (nonnull)
* @param string String pointer to initialise the object with, this string will not be copied
* and must remain valid for the lifetime of the object. (nonnull)
* @param length Length of the string.
*
* @return A pointer to the passed object or NULL if the operation failed.
*
* @note The provided string must have been allocated with the same allocator used
* with ddwaf_object_destroy.
**/
ddwaf_object* ddwaf_object_set_string_nocopy(ddwaf_object *object, const char *string, uint32_t length);
/**
* Creates an object using an unsigned integer (64-bit). The resulting object
* will contain an unsigned integer as opposed to a string.
*
* @param object Object to perform the operation on. (nonnull)
* @param value Integer to initialise the object with.
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_unsigned(ddwaf_object *object, uint64_t value);
/**
* Creates an object using a signed integer (64-bit). The resulting object
* will contain a signed integer as opposed to a string.
*
* @param object Object to perform the operation on. (nonnull)
* @param value Integer to initialise the object with.
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_signed(ddwaf_object *object, int64_t value);
/**
* Creates an object using a boolean, the resulting object will contain a
* boolean as opposed to a string.
*
* @param object Object to perform the operation on. (nonnull)
* @param value Boolean to initialise the object with.
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_bool(ddwaf_object *object, bool value);
/**
* Creates an object using a double, the resulting object will contain a
* double as opposed to a string.
*
* @param object Object to perform the operation on. (nonnull)
* @param value Double to initialise the object with.
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_float(ddwaf_object *object, double value);
/**
* Creates an array object for sequential storage.
*
* @param object Object to perform the operation on. (nonnull)
* @param capacity Initial capacity of the array.
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_array(ddwaf_object *object, uint16_t capacity, ddwaf_allocator alloc);
/**
* Creates an array object for sequential storage with a size_t initial
* capacity. Capacities above 65,535 use DDWAF_OBJ_LARGE_ARRAY. Large arrays are
* limited to the smaller of 268,435,455 elements and
* SIZE_MAX / sizeof(ddwaf_object).
*
* @warning This is a transitional ABI symbol. Source code must use
* ddwaf_object_set_array. This symbol will be removed in version 3.
*
* @param object Object to perform the operation on. (nonnull)
* @param capacity Initial capacity of the array.
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_array_large(ddwaf_object *object, size_t capacity, ddwaf_allocator alloc);
/**
* Creates a map object for key-value storage.
*
* @param object Object to perform the operation on. (nonnull)
* @param capacity Initial capacity of the map.
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_map(ddwaf_object *object, uint16_t capacity, ddwaf_allocator alloc);
/**
* Creates a map object for key-value storage with a size_t initial capacity.
* Capacities above 65,535 use DDWAF_OBJ_LARGE_MAP. Large maps are limited to
* the smaller of 268,435,455 entries and SIZE_MAX / sizeof(ddwaf_object_kv).
*
* @warning This is a transitional ABI symbol. Source code must use
* ddwaf_object_set_map. This symbol will be removed in version 3.
*
* @param object Object to perform the operation on. (nonnull)
* @param capacity Initial capacity of the map.
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the passed object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_set_map_large(ddwaf_object *object, size_t capacity, ddwaf_allocator alloc);
/**
* Inserts a new object into an array object.
*
* @param array Array in which to insert the object. (nonnull)
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the newly inserted object or NULL if the operation failed.
*
* @note An insertion that grows or promotes the array invalidates pointers to
* existing elements.
**/
ddwaf_object *ddwaf_object_insert(ddwaf_object *array, ddwaf_allocator alloc);
/**
* Inserts a new object into a map object, using a key.
*
* @param map Map in which to insert the object. (nonnull)
* @param key The key for indexing purposes, this string will be copied. (nonnull)
* @param length Length of the key.
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the newly inserted object or NULL if the operation failed.
*
* @note An insertion that grows or promotes the map invalidates pointers to
* existing keys and values.
**/
ddwaf_object *ddwaf_object_insert_key(ddwaf_object *map, const char *key, uint32_t length, ddwaf_allocator alloc);
/**
* Inserts a new object into a map object, using a literal key.
*
* @param map Map in which to insert the object. (nonnull)
* @param key The key for indexing purposes, this string will not be copied. (nonnull)
* @param length Length of the key.
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the newly inserted object or NULL if the operation failed.
*
* @note An insertion that grows or promotes the map invalidates pointers to
* existing keys and values.
**/
ddwaf_object *ddwaf_object_insert_literal_key(ddwaf_object *map, const char *key, uint32_t length, ddwaf_allocator alloc);
/**
* Inserts a new object into a map object, using a key and its length, but without
* creating a copy of the key.
*
* @param map Map in which to insert the object. (nonnull)
* @param key The key for indexing purposes, this string will not be copied. (nonnull)
* @param length Length of the key.
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the newly inserted object or NULL if the operation failed.
*
* @note The provided string must have been allocated with the same allocator used
* with ddwaf_object_destroy.
* @note An insertion that grows or promotes the map invalidates pointers to
* existing keys and values.
**/
ddwaf_object *ddwaf_object_insert_key_nocopy(ddwaf_object *map, const char *key, uint32_t length, ddwaf_allocator alloc);
/**
* Creates a ddwaf_object from a JSON string. The JSON will be parsed and converted
* into the appropriate ddwaf_object structure, supporting all JSON types including
* objects, arrays, strings, numbers, booleans, and null values.
*
* @param output Object to populate with the parsed JSON data. (nonnull)
* @param json_str The JSON string to parse. (nonnull)
* @param length Length of the JSON string.
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return The success or failure of the operation.
*
* @note The output object must be freed by the caller using ddwaf_object_free.
* @note If parsing fails, the output object will be left in an undefined state.
* @note The provided JSON string is owned by the caller.
**/
bool ddwaf_object_from_json(ddwaf_object *output, const char *json_str, uint32_t length, ddwaf_allocator alloc);
/**
* Returns the type of the object.
*
* @param object The object from which to get the type.
*
* @return The object type of DDWAF_OBJ_INVALID if NULL.
**/
DDWAF_OBJ_TYPE ddwaf_object_get_type(const ddwaf_object *object);
/**
* Returns the size of the container object.
*
* @param object The object from which to get the size.
*
* @return The object size or 0 if the object is not a container (array, map).
**/
size_t ddwaf_object_get_size(const ddwaf_object *object);
/**
* Returns the length of the string object.
*
* @param object The object from which to get the length.
*
* @return The string length or 0 if the object is not a string.
**/
size_t ddwaf_object_get_length(const ddwaf_object *object);
/**
* Returns the string contained within the object.
*
* @param object The object from which to get the string.
* @param length Output parameter on which to return the length of the string,
* this parameter is optional / nullable.
*
* @return The string of the object or NULL if the object is not a string.
**/
const char* ddwaf_object_get_string(const ddwaf_object *object, size_t *length);
/**
* Returns the uint64 contained within the object.
*
* @param object The object from which to get the integer.
*
* @return The integer or 0 if the object is not an unsigned.
**/
uint64_t ddwaf_object_get_unsigned(const ddwaf_object *object);
/**
* Returns the int64 contained within the object.
*
* @param object The object from which to get the integer.
*
* @return The integer or 0 if the object is not a signed.
**/
int64_t ddwaf_object_get_signed(const ddwaf_object *object);
/**
* Returns the float64 (double) contained within the object.
*
* @param object The object from which to get the float.
*
* @return The float or 0.0 if the object is not a float.
**/
double ddwaf_object_get_float(const ddwaf_object *object);
/**
* Returns the boolean contained within the object.
*
* @param object The object from which to get the boolean.
*
* @return The boolean or false if the object is not a boolean.
**/
bool ddwaf_object_get_bool(const ddwaf_object *object);
/**
* Returns the key contained in the container at the given index.
*
* @param object The container from which to extract the object.
* @param index The position of the required object within the container.
*
* @return The requested object or NULL if the index is out of bounds or the
* object is not a container.
**/
const ddwaf_object* ddwaf_object_at_key(const ddwaf_object *object, size_t index);
/**
* Returns the object contained in the container at the given index.
*
* @param object The container from which to extract the object.
* @param index The position of the required object within the container.
*
* @return The requested object or NULL if the index is out of bounds or the
* object is not a container.
**/
const ddwaf_object* ddwaf_object_at_value(const ddwaf_object *object, size_t index);
/**
* Returns the object within the given map with a key matching the provided one.
*
* @param object The container from which to extract the object.
* @param key A string representing the key to find.
* @param length Length of the key.
*
* @return The requested object or NULL if the key was not found or the
* object is not a container.
**/
const ddwaf_object* ddwaf_object_find(const ddwaf_object *object, const char *key, size_t length);
/**
* Creates a deep copy of the source object into the destination object.
*
* @param source The source object to clone from. (nonnull)
* @param destination The destination object to clone into. (nonnull)
* @param alloc Allocator to use for memory allocation. (nonnull)
*
* @return A pointer to the destination object or NULL if the operation failed.
**/
ddwaf_object* ddwaf_object_clone(const ddwaf_object *source, ddwaf_object *destination, ddwaf_allocator alloc);
/**
* Returns true if the object is invalid.
*
* @param object The object from which to get the type.
*
* @return True if the object is invalid, false otherwise.
**/
bool ddwaf_object_is_invalid(const ddwaf_object *object);
/**
* Returns true if the object is null.
*
* @param object The object from which to get the type.
*
* @return True if the object is null, false otherwise.
**/
bool ddwaf_object_is_null(const ddwaf_object *object);
/**
* Returns true if the object is a boolean.
*
* @param object The object from which to get the type.
*
* @return True if the object is a boolean, false otherwise.
**/
bool ddwaf_object_is_bool(const ddwaf_object *object);
/**
* Returns true if the object is a signed integer.
*
* @param object The object from which to get the type.
*
* @return True if the object is a signed integer, false otherwise.
**/
bool ddwaf_object_is_signed(const ddwaf_object *object);
/**
* Returns true if the object is an unsigned integer.
*
* @param object The object from which to get the type.
*
* @return True if the object is an unsigned integer, false otherwise.
**/
bool ddwaf_object_is_unsigned(const ddwaf_object *object);
/**
* Returns true if the object is a float.
*
* @param object The object from which to get the type.
*
* @return True if the object is a float, false otherwise.
**/
bool ddwaf_object_is_float(const ddwaf_object *object);
/**
* Returns true if the object is a string.
*
* @param object The object from which to get the type.
*
* @return True if the object is a string, false otherwise.
**/
bool ddwaf_object_is_string(const ddwaf_object *object);
/**
* Returns true if the object is an array.
*
* @param object The object from which to get the type.
*
* @return True if the object is an array, false otherwise.
**/
bool ddwaf_object_is_array(const ddwaf_object *object);
/**
* Returns true if the object is a map.
*
* @param object The object from which to get the type.
*
* @return True if the object is a map, false otherwise.
**/
bool ddwaf_object_is_map(const ddwaf_object *object);
/**
* Frees the memory contained within the object.
*
* @param object Object to destroy. (nonnull)
* @param alloc Allocator to use for memory reclamation. (nonnull)
**/
void ddwaf_object_destroy(ddwaf_object *object, ddwaf_allocator alloc);
/**
* Return the version of the library
*
* @return version Version string, note that this should not be freed
**/
const char *ddwaf_get_version();
/**
* Sets the callback to relay logging messages to the binding
*
* @param cb The callback to call, or NULL to stop relaying messages
* @param min_level The minimum logging level for which to relay messages
*
* @return whether the operation succeeded or not
*
* @note This function is not thread-safe
**/
bool ddwaf_set_log_cb(ddwaf_log_cb cb, DDWAF_LOG_LEVEL min_level);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#define ddwaf_object_set_array ddwaf_object_set_array_large
#define ddwaf_object_set_map ddwaf_object_set_map_large
/* The aliases above remain valid because they predate the poisoned identifiers. */
#if (defined(__GNUC__) || defined(__clang__)) && !defined(DDWAF_DISABLE_API_POISON)
#pragma GCC poison ddwaf_object_set_array_large ddwaf_object_set_map_large
#endif
#endif /*DDWAF_H */