@@ -78,6 +78,50 @@ TEST_CASE("aos update policy", "[tuple_sketch]") {
7878 input[1 ] = " changed" ;
7979 REQUIRE (values[1 ] == " second" );
8080 }
81+
82+ SECTION (" invalid utf8 rejected by default" ) {
83+ auto values = policy.create ();
84+
85+ array_of_strings input (1 , " " , std::allocator<std::string>());
86+ input[0 ] = std::string (" \xC3\x28 " , 2 );
87+ REQUIRE_THROWS_WITH (
88+ policy.update (values, input),
89+ Catch::Matchers::Contains (" invalid UTF-8 string" )
90+ );
91+ }
92+
93+ SECTION (" invalid utf8 rejected via pointer by default" ) {
94+ auto values = policy.create ();
95+
96+ array_of_strings input (1 , " " , std::allocator<std::string>());
97+ input[0 ] = std::string (" \xC3\x28 " , 2 );
98+ REQUIRE_THROWS_WITH (
99+ policy.update (values, &input),
100+ Catch::Matchers::Contains (" invalid UTF-8 string" )
101+ );
102+ }
103+
104+ SECTION (" invalid utf8 allowed when validation disabled" ) {
105+ default_array_of_strings_update_policy no_validate_policy (false );
106+ auto values = no_validate_policy.create ();
107+
108+ array_of_strings input (1 , " " , std::allocator<std::string>());
109+ input[0 ] = std::string (" \xC3\x28 " , 2 );
110+ REQUIRE_NOTHROW (no_validate_policy.update (values, input));
111+ REQUIRE (values.size () == 1 );
112+ REQUIRE (values[0 ] == std::string (" \xC3\x28 " , 2 ));
113+ }
114+
115+ SECTION (" invalid utf8 allowed via pointer when validation disabled" ) {
116+ default_array_of_strings_update_policy no_validate_policy (false );
117+ auto values = no_validate_policy.create ();
118+
119+ array_of_strings input (1 , " " , std::allocator<std::string>());
120+ input[0 ] = std::string (" \xC3\x28 " , 2 );
121+ REQUIRE_NOTHROW (no_validate_policy.update (values, &input));
122+ REQUIRE (values.size () == 1 );
123+ REQUIRE (values[0 ] == std::string (" \xC3\x28 " , 2 ));
124+ }
81125}
82126
83127TEST_CASE (" aos sketch update" , " [tuple_sketch]" ) {
@@ -254,26 +298,108 @@ TEST_CASE("aos sketch: serialize deserialize", "[tuple_sketch]") {
254298}
255299
256300TEST_CASE (" aos serde validation" , " [tuple_sketch]" ) {
257- default_array_of_strings_serde<> serde;
301+ default_array_of_strings_serde<> serde_no_validate;
302+ default_array_of_strings_serde<> serde_validate (std::allocator<array_of_strings>(), true );
258303
259- SECTION (" invalid utf8 rejected" ) {
260- array_of_strings array (1 , " " , std::allocator<std::string>());
261- const std::string invalid_utf8 (" \xC3\x28 " , 2 );
262- array[0 ] = invalid_utf8;
304+ auto make_invalid_array = []() {
305+ array_of_strings arr (1 , " " , std::allocator<std::string>());
306+ arr[0 ] = std::string (" \xC3\x28 " , 2 );
307+ return arr;
308+ };
309+
310+ auto serialize_to_stream = [&](const array_of_strings& arr) {
263311 std::stringstream ss;
264312 ss.exceptions (std::ios::failbit | std::ios::badbit);
313+ serde_no_validate.serialize (ss, &arr, 1 );
314+ return ss;
315+ };
316+
317+ auto serialize_to_bytes = [&](const array_of_strings& arr) {
318+ const size_t capacity = serde_no_validate.size_of_item (arr) + 64 ;
319+ std::vector<uint8_t > buf (capacity);
320+ const size_t written = serde_no_validate.serialize (buf.data (), capacity, &arr, 1 );
321+ buf.resize (written);
322+ return buf;
323+ };
324+
325+ SECTION (" stream serialize: invalid utf8 allowed by default" ) {
326+ auto arr = make_invalid_array ();
327+ std::stringstream ss;
328+ ss.exceptions (std::ios::failbit | std::ios::badbit);
329+ REQUIRE_NOTHROW (serde_no_validate.serialize (ss, &arr, 1 ));
330+ }
331+
332+ SECTION (" stream serialize: invalid utf8 rejected when validation enabled" ) {
333+ auto arr = make_invalid_array ();
334+ std::stringstream ss;
335+ ss.exceptions (std::ios::failbit | std::ios::badbit);
336+ REQUIRE_THROWS_WITH (
337+ serde_validate.serialize (ss, &arr, 1 ),
338+ Catch::Matchers::Contains (" invalid UTF-8" )
339+ );
340+ }
341+
342+ SECTION (" bytes serialize: invalid utf8 allowed by default" ) {
343+ auto arr = make_invalid_array ();
344+ const size_t capacity = serde_no_validate.size_of_item (arr) + 64 ;
345+ std::vector<uint8_t > buf (capacity);
346+ REQUIRE_NOTHROW (serde_no_validate.serialize (buf.data (), capacity, &arr, 1 ));
347+ }
348+
349+ SECTION (" bytes serialize: invalid utf8 rejected when validation enabled" ) {
350+ auto arr = make_invalid_array ();
351+ const size_t capacity = serde_validate.size_of_item (arr) + 64 ;
352+ std::vector<uint8_t > buf (capacity);
353+ REQUIRE_THROWS_WITH (
354+ serde_validate.serialize (buf.data (), capacity, &arr, 1 ),
355+ Catch::Matchers::Contains (" invalid UTF-8" )
356+ );
357+ }
358+
359+ SECTION (" stream deserialize: invalid utf8 allowed by default" ) {
360+ auto arr = make_invalid_array ();
361+ auto ss = serialize_to_stream (arr);
362+ array_of_strings result (0 , " " );
363+ REQUIRE_NOTHROW (serde_no_validate.deserialize (ss, &result, 1 ));
364+ REQUIRE (result.size () == 1 );
365+ REQUIRE (result[0 ] == std::string (" \xC3\x28 " , 2 ));
366+ }
367+
368+ SECTION (" stream deserialize: invalid utf8 rejected when validation enabled" ) {
369+ auto arr = make_invalid_array ();
370+ auto ss = serialize_to_stream (arr);
371+ array_of_strings result (0 , " " );
372+ REQUIRE_THROWS_WITH (
373+ serde_validate.deserialize (ss, &result, 1 ),
374+ Catch::Matchers::Contains (" invalid UTF-8" )
375+ );
376+ }
377+
378+ SECTION (" bytes deserialize: invalid utf8 allowed by default" ) {
379+ auto arr = make_invalid_array ();
380+ auto buf = serialize_to_bytes (arr);
381+ array_of_strings result (0 , " " );
382+ REQUIRE_NOTHROW (serde_no_validate.deserialize (buf.data (), buf.size (), &result, 1 ));
383+ REQUIRE (result.size () == 1 );
384+ REQUIRE (result[0 ] == std::string (" \xC3\x28 " , 2 ));
385+ }
386+
387+ SECTION (" bytes deserialize: invalid utf8 rejected when validation enabled" ) {
388+ auto arr = make_invalid_array ();
389+ auto buf = serialize_to_bytes (arr);
390+ array_of_strings result (0 , " " );
265391 REQUIRE_THROWS_WITH (
266- serde. serialize (ss, &array , 1 ),
392+ serde_validate. deserialize (buf. data (), buf. size (), &result , 1 ),
267393 Catch::Matchers::Contains (" invalid UTF-8" )
268394 );
269395 }
270396
271397 SECTION (" too many nodes rejected" ) {
272- array_of_strings array (128 , " " , std::allocator<std::string>());
398+ array_of_strings arr (128 , " " , std::allocator<std::string>());
273399 std::stringstream ss;
274400 ss.exceptions (std::ios::failbit | std::ios::badbit);
275401 REQUIRE_THROWS_WITH (
276- serde .serialize (ss, &array , 1 ),
402+ serde_no_validate .serialize (ss, &arr , 1 ),
277403 Catch::Matchers::Contains (" size exceeds 127" )
278404 );
279405 }
0 commit comments