99
1010#include < limits>
1111#include < string>
12+ #include < algorithm>
1213
1314#include " src/convert.h"
1415#include " src/log.h"
@@ -21,7 +22,8 @@ ddwaf_object* to_ddwaf_object(
2122 int depth,
2223 bool lim,
2324 bool ignoreToJSON,
24- JsSet stack
25+ JsSet stack,
26+ WAFTruncationMetrics* metrics
2527);
2628
2729ddwaf_object* to_ddwaf_object_array (
@@ -31,12 +33,13 @@ ddwaf_object* to_ddwaf_object_array(
3133 int depth,
3234 bool lim,
3335 bool ignoreToJSON,
34- JsSet stack
36+ JsSet stack,
37+ WAFTruncationMetrics* metrics
3538) {
3639 if (!ignoreToJSON) {
3740 Napi::Value toJSON = arr.Get (" toJSON" );
3841 if (toJSON.IsFunction ()) {
39- return to_ddwaf_object (object, env, toJSON.As <Napi::Function>().Call (arr, {}), depth, lim, true , stack);
42+ return to_ddwaf_object (object, env, toJSON.As <Napi::Function>().Call (arr, {}), depth, lim, true , stack, metrics );
4043 }
4144 }
4245
@@ -53,12 +56,16 @@ ddwaf_object* to_ddwaf_object_array(
5356 // TODO(@vdeturckheim): handle arrays with
5457 // more than DDWAF_MAX_CONTAINER_SIZE chars
5558 if (lim && len > DDWAF_MAX_CONTAINER_SIZE) {
59+ if (metrics) {
60+ metrics->max_truncated_container_size = std::max (metrics->max_truncated_container_size ,
61+ static_cast <size_t >(len));
62+ }
5663 len = DDWAF_MAX_CONTAINER_SIZE;
5764 }
5865 for (uint32_t i = 0 ; i < len; ++i) {
5966 Napi::Value item = arr.Get (i);
6067 ddwaf_object val;
61- to_ddwaf_object (&val, env, item, depth, lim, false , stack);
68+ to_ddwaf_object (&val, env, item, depth, lim, false , stack, metrics );
6269 if (!ddwaf_object_array_add (object, &val)) {
6370 mlog (" add to array failed, freeing" );
6471 ddwaf_object_free (&val);
@@ -75,18 +82,23 @@ ddwaf_object* to_ddwaf_object_object(
7582 int depth,
7683 bool lim,
7784 bool ignoreToJSON,
78- JsSet stack
85+ JsSet stack,
86+ WAFTruncationMetrics* metrics
7987) {
8088 if (!ignoreToJSON) {
8189 Napi::Value toJSON = obj.Get (" toJSON" );
8290 if (toJSON.IsFunction ()) {
83- return to_ddwaf_object (object, env, toJSON.As <Napi::Function>().Call (obj, {}), depth, lim, true , stack);
91+ return to_ddwaf_object (object, env, toJSON.As <Napi::Function>().Call (obj, {}), depth, lim, true , stack, metrics );
8492 }
8593 }
8694
8795 Napi::Array properties = obj.GetPropertyNames ();
8896 uint32_t len = properties.Length ();
8997 if (lim && len > DDWAF_MAX_CONTAINER_SIZE) {
98+ if (metrics) {
99+ metrics->max_truncated_container_size = std::max (metrics->max_truncated_container_size ,
100+ static_cast <size_t >(len));
101+ }
90102 len = DDWAF_MAX_CONTAINER_SIZE;
91103 }
92104 if (env.IsExceptionPending ()) {
@@ -112,7 +124,7 @@ ddwaf_object* to_ddwaf_object_object(
112124 Napi::Value valV = obj.Get (keyV);
113125 mlog (" Looping into ToPWArgs" );
114126 ddwaf_object val;
115- to_ddwaf_object (&val, env, valV, depth, lim, false , stack);
127+ to_ddwaf_object (&val, env, valV, depth, lim, false , stack, metrics );
116128 if (!ddwaf_object_map_add (map, key.c_str (), &val)) {
117129 mlog (" add to object failed, freeing" );
118130 ddwaf_object_free (&val);
@@ -122,10 +134,19 @@ ddwaf_object* to_ddwaf_object_object(
122134 return object;
123135}
124136
125- ddwaf_object* to_ddwaf_string (ddwaf_object *object, Napi::Value val, bool lim) {
137+ ddwaf_object* to_ddwaf_string (
138+ ddwaf_object *object,
139+ Napi::Value val,
140+ bool lim,
141+ WAFTruncationMetrics* metrics
142+ ) {
126143 std::string str = val.ToString ().Utf8Value ();
127144 int len = str.length ();
128145 if (lim && len > DDWAF_MAX_STRING_LENGTH) {
146+ if (metrics) {
147+ metrics->max_truncated_string_length = std::max (metrics->max_truncated_string_length ,
148+ static_cast <size_t >(len));
149+ }
129150 len = DDWAF_MAX_STRING_LENGTH;
130151 }
131152 return ddwaf_object_stringl (object, str.c_str (), len);
@@ -138,11 +159,16 @@ ddwaf_object* to_ddwaf_object(
138159 int depth,
139160 bool lim,
140161 bool ignoreToJson,
141- JsSet stack
162+ JsSet stack,
163+ WAFTruncationMetrics* metrics
142164) {
143165 mlog (" starting to convert an object" );
144166 if (depth >= DDWAF_MAX_CONTAINER_DEPTH) {
145167 mlog (" Max depth reached" );
168+ if (metrics) {
169+ metrics->max_truncated_container_depth = std::max (metrics->max_truncated_container_depth ,
170+ static_cast <size_t >(depth));
171+ }
146172 return ddwaf_object_map (object);
147173 }
148174 if (val.IsNull ()) {
@@ -151,7 +177,7 @@ ddwaf_object* to_ddwaf_object(
151177 }
152178 if (val.IsString ()) {
153179 mlog (" creating String" );
154- return to_ddwaf_string (object, val, lim);
180+ return to_ddwaf_string (object, val, lim, metrics );
155181 }
156182 if (val.IsNumber ()) {
157183 mlog (" creating Number" );
@@ -190,32 +216,22 @@ ddwaf_object* to_ddwaf_object(
190216 stack.Add (val);
191217 mlog (" creating Array" );
192218 auto result =
193- to_ddwaf_object_array (object, env, val.ToObject ().As <Napi::Array>(), depth + 1 , lim, ignoreToJson, stack);
219+ to_ddwaf_object_array (object, env, val.ToObject ().As <Napi::Array>(), depth + 1 , lim, ignoreToJson, stack,
220+ metrics);
194221 stack.Delete (val);
195222 return result;
196223 }
197224 if (val.IsObject ()) {
198225 stack.Add (val);
199226 mlog (" creating Object" );
200- auto result = to_ddwaf_object_object (object, env, val.ToObject (), depth + 1 , lim, ignoreToJson, stack);
227+ auto result = to_ddwaf_object_object (object, env, val.ToObject (), depth + 1 , lim, ignoreToJson, stack, metrics );
201228 stack.Delete (val);
202229 return result;
203230 }
204231 mlog (" creating invalid object" );
205232 return ddwaf_object_invalid (object);
206233}
207234
208- ddwaf_object* to_ddwaf_object (
209- ddwaf_object *object,
210- Napi::Env env,
211- Napi::Value val,
212- int depth,
213- bool lim,
214- bool ignoreToJson
215- ) {
216- return to_ddwaf_object (object, env, val, depth, lim, ignoreToJson, JsSet::Create (env));
217- }
218-
219235Napi::Value from_ddwaf_object (ddwaf_object *object, Napi::Env env) {
220236 DDWAF_OBJ_TYPE type = object->type ;
221237
0 commit comments