error_handling_test.cc (41832B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include <cstddef> 7 #include <cstdint> 8 #include <cstdlib> 9 #include <cstring> 10 #include <vector> 11 12 #include "lib/jpegli/common.h" 13 #include "lib/jpegli/decode.h" 14 #include "lib/jpegli/encode.h" 15 #include "lib/jpegli/libjpeg_test_util.h" 16 #include "lib/jpegli/test_params.h" 17 #include "lib/jpegli/test_utils.h" 18 #include "lib/jpegli/testing.h" 19 20 namespace jpegli { 21 namespace { 22 23 TEST(EncoderErrorHandlingTest, MinimalSuccess) { 24 uint8_t* buffer = nullptr; 25 unsigned long buffer_size = 0; // NOLINT 26 { 27 jpeg_compress_struct cinfo; 28 const auto try_catch_block = [&]() -> bool { 29 ERROR_HANDLER_SETUP(jpegli); 30 jpegli_create_compress(&cinfo); 31 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 32 cinfo.image_width = 1; 33 cinfo.image_height = 1; 34 cinfo.input_components = 1; 35 jpegli_set_defaults(&cinfo); 36 jpegli_start_compress(&cinfo, TRUE); 37 JSAMPLE image[1] = {0}; 38 JSAMPROW row[] = {image}; 39 jpegli_write_scanlines(&cinfo, row, 1); 40 jpegli_finish_compress(&cinfo); 41 return true; 42 }; 43 EXPECT_TRUE(try_catch_block()); 44 jpegli_destroy_compress(&cinfo); 45 } 46 TestImage output; 47 DecodeWithLibjpeg(CompressParams(), DecompressParams(), nullptr, 0, buffer, 48 buffer_size, &output); 49 EXPECT_EQ(1, output.xsize); 50 EXPECT_EQ(1, output.ysize); 51 EXPECT_EQ(1, output.components); 52 EXPECT_EQ(0, output.pixels[0]); 53 if (buffer) free(buffer); 54 } 55 56 TEST(EncoderErrorHandlingTest, NoDestination) { 57 jpeg_compress_struct cinfo; 58 const auto try_catch_block = [&]() -> bool { 59 ERROR_HANDLER_SETUP(jpegli); 60 jpegli_create_compress(&cinfo); 61 cinfo.image_width = 1; 62 cinfo.image_height = 1; 63 cinfo.input_components = 1; 64 jpegli_set_defaults(&cinfo); 65 jpegli_start_compress(&cinfo, TRUE); 66 return true; 67 }; 68 EXPECT_FALSE(try_catch_block()); 69 jpegli_destroy_compress(&cinfo); 70 } 71 72 TEST(EncoderErrorHandlingTest, NoImageDimensions) { 73 uint8_t* buffer = nullptr; 74 unsigned long buffer_size = 0; // NOLINT 75 jpeg_compress_struct cinfo; 76 const auto try_catch_block = [&]() -> bool { 77 ERROR_HANDLER_SETUP(jpegli); 78 jpegli_create_compress(&cinfo); 79 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 80 cinfo.input_components = 1; 81 jpegli_set_defaults(&cinfo); 82 jpegli_start_compress(&cinfo, TRUE); 83 return true; 84 }; 85 EXPECT_FALSE(try_catch_block()); 86 jpegli_destroy_compress(&cinfo); 87 if (buffer) free(buffer); 88 } 89 90 TEST(EncoderErrorHandlingTest, ImageTooBig) { 91 uint8_t* buffer = nullptr; 92 unsigned long buffer_size = 0; // NOLINT 93 jpeg_compress_struct cinfo; 94 const auto try_catch_block = [&]() -> bool { 95 ERROR_HANDLER_SETUP(jpegli); 96 jpegli_create_compress(&cinfo); 97 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 98 cinfo.image_width = 100000; 99 cinfo.image_height = 1; 100 cinfo.input_components = 1; 101 jpegli_set_defaults(&cinfo); 102 jpegli_start_compress(&cinfo, TRUE); 103 return true; 104 }; 105 EXPECT_FALSE(try_catch_block()); 106 jpegli_destroy_compress(&cinfo); 107 if (buffer) free(buffer); 108 } 109 110 TEST(EncoderErrorHandlingTest, NoInputComponents) { 111 uint8_t* buffer = nullptr; 112 unsigned long buffer_size = 0; // NOLINT 113 jpeg_compress_struct cinfo; 114 const auto try_catch_block = [&]() -> bool { 115 ERROR_HANDLER_SETUP(jpegli); 116 jpegli_create_compress(&cinfo); 117 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 118 cinfo.image_width = 1; 119 cinfo.image_height = 1; 120 jpegli_set_defaults(&cinfo); 121 jpegli_start_compress(&cinfo, TRUE); 122 return true; 123 }; 124 EXPECT_FALSE(try_catch_block()); 125 jpegli_destroy_compress(&cinfo); 126 if (buffer) free(buffer); 127 } 128 129 TEST(EncoderErrorHandlingTest, TooManyInputComponents) { 130 uint8_t* buffer = nullptr; 131 unsigned long buffer_size = 0; // NOLINT 132 jpeg_compress_struct cinfo; 133 const auto try_catch_block = [&]() -> bool { 134 ERROR_HANDLER_SETUP(jpegli); 135 jpegli_create_compress(&cinfo); 136 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 137 cinfo.image_width = 1; 138 cinfo.image_height = 1; 139 cinfo.input_components = 1000; 140 jpegli_set_defaults(&cinfo); 141 jpegli_start_compress(&cinfo, TRUE); 142 return true; 143 }; 144 EXPECT_FALSE(try_catch_block()); 145 jpegli_destroy_compress(&cinfo); 146 if (buffer) free(buffer); 147 } 148 149 TEST(EncoderErrorHandlingTest, NoSetDefaults) { 150 uint8_t* buffer = nullptr; 151 unsigned long buffer_size = 0; // NOLINT 152 jpeg_compress_struct cinfo; 153 const auto try_catch_block = [&]() -> bool { 154 ERROR_HANDLER_SETUP(jpegli); 155 jpegli_create_compress(&cinfo); 156 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 157 cinfo.image_width = 1; 158 cinfo.image_height = 1; 159 cinfo.input_components = 1; 160 jpegli_start_compress(&cinfo, TRUE); 161 JSAMPLE image[1] = {0}; 162 JSAMPROW row[] = {image}; 163 jpegli_write_scanlines(&cinfo, row, 1); 164 jpegli_finish_compress(&cinfo); 165 return true; 166 }; 167 EXPECT_FALSE(try_catch_block()); 168 jpegli_destroy_compress(&cinfo); 169 if (buffer) free(buffer); 170 } 171 172 TEST(EncoderErrorHandlingTest, NoStartCompress) { 173 uint8_t* buffer = nullptr; 174 unsigned long buffer_size = 0; // NOLINT 175 jpeg_compress_struct cinfo; 176 const auto try_catch_block = [&]() -> bool { 177 ERROR_HANDLER_SETUP(jpegli); 178 jpegli_create_compress(&cinfo); 179 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 180 cinfo.image_width = 1; 181 cinfo.image_height = 1; 182 cinfo.input_components = 1; 183 jpegli_set_defaults(&cinfo); 184 JSAMPLE image[1] = {0}; 185 JSAMPROW row[] = {image}; 186 jpegli_write_scanlines(&cinfo, row, 1); 187 return true; 188 }; 189 EXPECT_FALSE(try_catch_block()); 190 jpegli_destroy_compress(&cinfo); 191 if (buffer) free(buffer); 192 } 193 194 TEST(EncoderErrorHandlingTest, NoWriteScanlines) { 195 uint8_t* buffer = nullptr; 196 unsigned long buffer_size = 0; // NOLINT 197 jpeg_compress_struct cinfo; 198 const auto try_catch_block = [&]() -> bool { 199 ERROR_HANDLER_SETUP(jpegli); 200 jpegli_create_compress(&cinfo); 201 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 202 cinfo.image_width = 1; 203 cinfo.image_height = 1; 204 cinfo.input_components = 1; 205 jpegli_set_defaults(&cinfo); 206 jpegli_start_compress(&cinfo, TRUE); 207 jpegli_finish_compress(&cinfo); 208 return true; 209 }; 210 EXPECT_FALSE(try_catch_block()); 211 jpegli_destroy_compress(&cinfo); 212 if (buffer) free(buffer); 213 } 214 215 TEST(EncoderErrorHandlingTest, NoWriteAllScanlines) { 216 uint8_t* buffer = nullptr; 217 unsigned long buffer_size = 0; // NOLINT 218 jpeg_compress_struct cinfo; 219 const auto try_catch_block = [&]() -> bool { 220 ERROR_HANDLER_SETUP(jpegli); 221 jpegli_create_compress(&cinfo); 222 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 223 cinfo.image_width = 1; 224 cinfo.image_height = 2; 225 cinfo.input_components = 1; 226 jpegli_set_defaults(&cinfo); 227 jpegli_start_compress(&cinfo, TRUE); 228 JSAMPLE image[1] = {0}; 229 JSAMPROW row[] = {image}; 230 jpegli_write_scanlines(&cinfo, row, 1); 231 jpegli_finish_compress(&cinfo); 232 return true; 233 }; 234 EXPECT_FALSE(try_catch_block()); 235 jpegli_destroy_compress(&cinfo); 236 if (buffer) free(buffer); 237 } 238 239 TEST(EncoderErrorHandlingTest, InvalidQuantValue) { 240 uint8_t* buffer = nullptr; 241 unsigned long buffer_size = 0; // NOLINT 242 jpeg_compress_struct cinfo; 243 const auto try_catch_block = [&]() -> bool { 244 ERROR_HANDLER_SETUP(jpegli); 245 jpegli_create_compress(&cinfo); 246 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 247 cinfo.image_width = 1; 248 cinfo.image_height = 1; 249 cinfo.input_components = 1; 250 jpegli_set_defaults(&cinfo); 251 cinfo.quant_tbl_ptrs[0] = 252 jpegli_alloc_quant_table(reinterpret_cast<j_common_ptr>(&cinfo)); 253 for (UINT16& q : cinfo.quant_tbl_ptrs[0]->quantval) { 254 q = 0; 255 } 256 jpegli_start_compress(&cinfo, TRUE); 257 JSAMPLE image[1] = {0}; 258 JSAMPROW row[] = {image}; 259 jpegli_write_scanlines(&cinfo, row, 1); 260 jpegli_finish_compress(&cinfo); 261 return true; 262 }; 263 EXPECT_FALSE(try_catch_block()); 264 jpegli_destroy_compress(&cinfo); 265 if (buffer) free(buffer); 266 } 267 268 TEST(EncoderErrorHandlingTest, InvalidQuantTableIndex) { 269 uint8_t* buffer = nullptr; 270 unsigned long buffer_size = 0; // NOLINT 271 jpeg_compress_struct cinfo; 272 const auto try_catch_block = [&]() -> bool { 273 ERROR_HANDLER_SETUP(jpegli); 274 jpegli_create_compress(&cinfo); 275 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 276 cinfo.image_width = 1; 277 cinfo.image_height = 1; 278 cinfo.input_components = 1; 279 jpegli_set_defaults(&cinfo); 280 cinfo.comp_info[0].quant_tbl_no = 3; 281 jpegli_start_compress(&cinfo, TRUE); 282 JSAMPLE image[1] = {0}; 283 JSAMPROW row[] = {image}; 284 jpegli_write_scanlines(&cinfo, row, 1); 285 jpegli_finish_compress(&cinfo); 286 return true; 287 }; 288 EXPECT_FALSE(try_catch_block()); 289 jpegli_destroy_compress(&cinfo); 290 if (buffer) free(buffer); 291 } 292 293 TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch1) { 294 uint8_t* buffer = nullptr; 295 unsigned long buffer_size = 0; // NOLINT 296 jpeg_compress_struct cinfo; 297 const auto try_catch_block = [&]() -> bool { 298 ERROR_HANDLER_SETUP(jpegli); 299 jpegli_create_compress(&cinfo); 300 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 301 cinfo.image_width = 1; 302 cinfo.image_height = 1; 303 cinfo.input_components = 1; 304 jpegli_set_defaults(&cinfo); 305 cinfo.num_components = 100; 306 jpegli_start_compress(&cinfo, TRUE); 307 return true; 308 }; 309 EXPECT_FALSE(try_catch_block()); 310 jpegli_destroy_compress(&cinfo); 311 if (buffer) free(buffer); 312 } 313 314 TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch2) { 315 uint8_t* buffer = nullptr; 316 unsigned long buffer_size = 0; // NOLINT 317 jpeg_compress_struct cinfo; 318 const auto try_catch_block = [&]() -> bool { 319 ERROR_HANDLER_SETUP(jpegli); 320 jpegli_create_compress(&cinfo); 321 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 322 cinfo.image_width = 1; 323 cinfo.image_height = 1; 324 cinfo.input_components = 1; 325 jpegli_set_defaults(&cinfo); 326 cinfo.num_components = 2; 327 jpegli_start_compress(&cinfo, TRUE); 328 return true; 329 }; 330 EXPECT_FALSE(try_catch_block()); 331 jpegli_destroy_compress(&cinfo); 332 if (buffer) free(buffer); 333 } 334 335 TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch3) { 336 uint8_t* buffer = nullptr; 337 unsigned long buffer_size = 0; // NOLINT 338 jpeg_compress_struct cinfo; 339 const auto try_catch_block = [&]() -> bool { 340 ERROR_HANDLER_SETUP(jpegli); 341 jpegli_create_compress(&cinfo); 342 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 343 cinfo.image_width = 1; 344 cinfo.image_height = 1; 345 cinfo.input_components = 1; 346 jpegli_set_defaults(&cinfo); 347 cinfo.num_components = 2; 348 cinfo.comp_info[1].h_samp_factor = cinfo.comp_info[1].v_samp_factor = 1; 349 jpegli_start_compress(&cinfo, TRUE); 350 JSAMPLE image[1] = {0}; 351 JSAMPROW row[] = {image}; 352 jpegli_write_scanlines(&cinfo, row, 1); 353 jpegli_finish_compress(&cinfo); 354 return true; 355 }; 356 EXPECT_FALSE(try_catch_block()); 357 jpegli_destroy_compress(&cinfo); 358 if (buffer) free(buffer); 359 } 360 361 TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch4) { 362 uint8_t* buffer = nullptr; 363 unsigned long buffer_size = 0; // NOLINT 364 jpeg_compress_struct cinfo; 365 const auto try_catch_block = [&]() -> bool { 366 ERROR_HANDLER_SETUP(jpegli); 367 jpegli_create_compress(&cinfo); 368 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 369 cinfo.image_width = 1; 370 cinfo.image_height = 1; 371 cinfo.input_components = 1; 372 cinfo.in_color_space = JCS_RGB; 373 jpegli_set_defaults(&cinfo); 374 jpegli_start_compress(&cinfo, TRUE); 375 JSAMPLE image[1] = {0}; 376 JSAMPROW row[] = {image}; 377 jpegli_write_scanlines(&cinfo, row, 1); 378 jpegli_finish_compress(&cinfo); 379 return true; 380 }; 381 EXPECT_FALSE(try_catch_block()); 382 jpegli_destroy_compress(&cinfo); 383 if (buffer) free(buffer); 384 } 385 386 TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch5) { 387 uint8_t* buffer = nullptr; 388 unsigned long buffer_size = 0; // NOLINT 389 jpeg_compress_struct cinfo; 390 const auto try_catch_block = [&]() -> bool { 391 ERROR_HANDLER_SETUP(jpegli); 392 jpegli_create_compress(&cinfo); 393 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 394 cinfo.image_width = 1; 395 cinfo.image_height = 1; 396 cinfo.input_components = 3; 397 cinfo.in_color_space = JCS_GRAYSCALE; 398 jpegli_set_defaults(&cinfo); 399 jpegli_start_compress(&cinfo, TRUE); 400 JSAMPLE image[3] = {0}; 401 JSAMPROW row[] = {image}; 402 jpegli_write_scanlines(&cinfo, row, 1); 403 jpegli_finish_compress(&cinfo); 404 return true; 405 }; 406 EXPECT_FALSE(try_catch_block()); 407 jpegli_destroy_compress(&cinfo); 408 if (buffer) free(buffer); 409 } 410 411 TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch6) { 412 uint8_t* buffer = nullptr; 413 unsigned long buffer_size = 0; // NOLINT 414 jpeg_compress_struct cinfo; 415 const auto try_catch_block = [&]() -> bool { 416 ERROR_HANDLER_SETUP(jpegli); 417 jpegli_create_compress(&cinfo); 418 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 419 cinfo.image_width = 1; 420 cinfo.image_height = 1; 421 cinfo.input_components = 3; 422 cinfo.in_color_space = JCS_RGB; 423 jpegli_set_defaults(&cinfo); 424 cinfo.num_components = 2; 425 jpegli_start_compress(&cinfo, TRUE); 426 JSAMPLE image[3] = {0}; 427 JSAMPROW row[] = {image}; 428 jpegli_write_scanlines(&cinfo, row, 1); 429 jpegli_finish_compress(&cinfo); 430 return true; 431 }; 432 EXPECT_FALSE(try_catch_block()); 433 jpegli_destroy_compress(&cinfo); 434 if (buffer) free(buffer); 435 } 436 437 TEST(EncoderErrorHandlingTest, InvalidColorTransform) { 438 uint8_t* buffer = nullptr; 439 unsigned long buffer_size = 0; // NOLINT 440 jpeg_compress_struct cinfo; 441 const auto try_catch_block = [&]() -> bool { 442 ERROR_HANDLER_SETUP(jpegli); 443 jpegli_create_compress(&cinfo); 444 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 445 cinfo.image_width = 1; 446 cinfo.image_height = 1; 447 cinfo.input_components = 3; 448 cinfo.in_color_space = JCS_YCbCr; 449 jpegli_set_defaults(&cinfo); 450 cinfo.jpeg_color_space = JCS_RGB; 451 jpegli_start_compress(&cinfo, TRUE); 452 JSAMPLE image[3] = {0}; 453 JSAMPROW row[] = {image}; 454 jpegli_write_scanlines(&cinfo, row, 1); 455 jpegli_finish_compress(&cinfo); 456 return true; 457 }; 458 EXPECT_FALSE(try_catch_block()); 459 jpegli_destroy_compress(&cinfo); 460 if (buffer) free(buffer); 461 } 462 463 TEST(EncoderErrorHandlingTest, DuplicateComponentIds) { 464 uint8_t* buffer = nullptr; 465 unsigned long buffer_size = 0; // NOLINT 466 jpeg_compress_struct cinfo; 467 const auto try_catch_block = [&]() -> bool { 468 ERROR_HANDLER_SETUP(jpegli); 469 jpegli_create_compress(&cinfo); 470 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 471 cinfo.image_width = 1; 472 cinfo.image_height = 1; 473 cinfo.input_components = 3; 474 jpegli_set_defaults(&cinfo); 475 cinfo.comp_info[0].component_id = 0; 476 cinfo.comp_info[1].component_id = 0; 477 jpegli_start_compress(&cinfo, TRUE); 478 return true; 479 }; 480 EXPECT_FALSE(try_catch_block()); 481 jpegli_destroy_compress(&cinfo); 482 if (buffer) free(buffer); 483 } 484 485 TEST(EncoderErrorHandlingTest, InvalidComponentIndex) { 486 uint8_t* buffer = nullptr; 487 unsigned long buffer_size = 0; // NOLINT 488 jpeg_compress_struct cinfo; 489 const auto try_catch_block = [&]() -> bool { 490 ERROR_HANDLER_SETUP(jpegli); 491 jpegli_create_compress(&cinfo); 492 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 493 cinfo.image_width = 1; 494 cinfo.image_height = 1; 495 cinfo.input_components = 3; 496 jpegli_set_defaults(&cinfo); 497 cinfo.comp_info[0].component_index = 17; 498 jpegli_start_compress(&cinfo, TRUE); 499 return true; 500 }; 501 EXPECT_FALSE(try_catch_block()); 502 jpegli_destroy_compress(&cinfo); 503 if (buffer) free(buffer); 504 } 505 506 TEST(EncoderErrorHandlingTest, ArithmeticCoding) { 507 uint8_t* buffer = nullptr; 508 unsigned long buffer_size = 0; // NOLINT 509 jpeg_compress_struct cinfo; 510 const auto try_catch_block = [&]() -> bool { 511 ERROR_HANDLER_SETUP(jpegli); 512 jpegli_create_compress(&cinfo); 513 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 514 cinfo.image_width = 1; 515 cinfo.image_height = 1; 516 cinfo.input_components = 3; 517 jpegli_set_defaults(&cinfo); 518 cinfo.arith_code = TRUE; 519 jpegli_start_compress(&cinfo, TRUE); 520 return true; 521 }; 522 EXPECT_FALSE(try_catch_block()); 523 jpegli_destroy_compress(&cinfo); 524 if (buffer) free(buffer); 525 } 526 527 TEST(EncoderErrorHandlingTest, CCIR601Sampling) { 528 uint8_t* buffer = nullptr; 529 unsigned long buffer_size = 0; // NOLINT 530 jpeg_compress_struct cinfo; 531 const auto try_catch_block = [&]() -> bool { 532 ERROR_HANDLER_SETUP(jpegli); 533 jpegli_create_compress(&cinfo); 534 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 535 cinfo.image_width = 1; 536 cinfo.image_height = 1; 537 cinfo.input_components = 3; 538 jpegli_set_defaults(&cinfo); 539 cinfo.CCIR601_sampling = TRUE; 540 jpegli_start_compress(&cinfo, TRUE); 541 return true; 542 }; 543 EXPECT_FALSE(try_catch_block()); 544 jpegli_destroy_compress(&cinfo); 545 if (buffer) free(buffer); 546 } 547 548 TEST(EncoderErrorHandlingTest, InvalidScanScript1) { 549 uint8_t* buffer = nullptr; 550 unsigned long buffer_size = 0; // NOLINT 551 jpeg_compress_struct cinfo; 552 const auto try_catch_block = [&]() -> bool { 553 ERROR_HANDLER_SETUP(jpegli); 554 jpegli_create_compress(&cinfo); 555 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 556 cinfo.image_width = 1; 557 cinfo.image_height = 1; 558 cinfo.input_components = 1; 559 jpegli_set_defaults(&cinfo); 560 static constexpr jpeg_scan_info kScript[] = {{1, {0}, 0, 63, 0, 0}}; // 561 cinfo.scan_info = kScript; 562 cinfo.num_scans = 0; 563 jpegli_start_compress(&cinfo, TRUE); 564 return true; 565 }; 566 EXPECT_FALSE(try_catch_block()); 567 jpegli_destroy_compress(&cinfo); 568 if (buffer) free(buffer); 569 } 570 571 TEST(EncoderErrorHandlingTest, InvalidScanScript2) { 572 uint8_t* buffer = nullptr; 573 unsigned long buffer_size = 0; // NOLINT 574 jpeg_compress_struct cinfo; 575 const auto try_catch_block = [&]() -> bool { 576 ERROR_HANDLER_SETUP(jpegli); 577 jpegli_create_compress(&cinfo); 578 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 579 cinfo.image_width = 1; 580 cinfo.image_height = 1; 581 cinfo.input_components = 1; 582 jpegli_set_defaults(&cinfo); 583 static constexpr jpeg_scan_info kScript[] = {{2, {0, 1}, 0, 63, 0, 0}}; // 584 cinfo.scan_info = kScript; 585 cinfo.num_scans = ARRAY_SIZE(kScript); 586 jpegli_start_compress(&cinfo, TRUE); 587 return true; 588 }; 589 EXPECT_FALSE(try_catch_block()); 590 jpegli_destroy_compress(&cinfo); 591 if (buffer) free(buffer); 592 } 593 594 TEST(EncoderErrorHandlingTest, InvalidScanScript3) { 595 uint8_t* buffer = nullptr; 596 unsigned long buffer_size = 0; // NOLINT 597 jpeg_compress_struct cinfo; 598 const auto try_catch_block = [&]() -> bool { 599 ERROR_HANDLER_SETUP(jpegli); 600 jpegli_create_compress(&cinfo); 601 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 602 cinfo.image_width = 1; 603 cinfo.image_height = 1; 604 cinfo.input_components = 1; 605 jpegli_set_defaults(&cinfo); 606 static constexpr jpeg_scan_info kScript[] = {{5, {0}, 0, 63, 0, 0}}; // 607 cinfo.scan_info = kScript; 608 cinfo.num_scans = ARRAY_SIZE(kScript); 609 jpegli_start_compress(&cinfo, TRUE); 610 return true; 611 }; 612 EXPECT_FALSE(try_catch_block()); 613 jpegli_destroy_compress(&cinfo); 614 if (buffer) free(buffer); 615 } 616 617 TEST(EncoderErrorHandlingTest, InvalidScanScript4) { 618 uint8_t* buffer = nullptr; 619 unsigned long buffer_size = 0; // NOLINT 620 jpeg_compress_struct cinfo; 621 const auto try_catch_block = [&]() -> bool { 622 ERROR_HANDLER_SETUP(jpegli); 623 jpegli_create_compress(&cinfo); 624 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 625 cinfo.image_width = 1; 626 cinfo.image_height = 1; 627 cinfo.input_components = 2; 628 jpegli_set_defaults(&cinfo); 629 static constexpr jpeg_scan_info kScript[] = {{2, {0, 0}, 0, 63, 0, 0}}; // 630 cinfo.scan_info = kScript; 631 cinfo.num_scans = ARRAY_SIZE(kScript); 632 jpegli_start_compress(&cinfo, TRUE); 633 return true; 634 }; 635 EXPECT_FALSE(try_catch_block()); 636 jpegli_destroy_compress(&cinfo); 637 if (buffer) free(buffer); 638 } 639 640 TEST(EncoderErrorHandlingTest, InvalidScanScript5) { 641 uint8_t* buffer = nullptr; 642 unsigned long buffer_size = 0; // NOLINT 643 jpeg_compress_struct cinfo; 644 const auto try_catch_block = [&]() -> bool { 645 ERROR_HANDLER_SETUP(jpegli); 646 jpegli_create_compress(&cinfo); 647 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 648 cinfo.image_width = 1; 649 cinfo.image_height = 1; 650 cinfo.input_components = 2; 651 jpegli_set_defaults(&cinfo); 652 static constexpr jpeg_scan_info kScript[] = {{2, {1, 0}, 0, 63, 0, 0}}; // 653 cinfo.scan_info = kScript; 654 cinfo.num_scans = ARRAY_SIZE(kScript); 655 jpegli_start_compress(&cinfo, TRUE); 656 return true; 657 }; 658 EXPECT_FALSE(try_catch_block()); 659 jpegli_destroy_compress(&cinfo); 660 if (buffer) free(buffer); 661 } 662 663 TEST(EncoderErrorHandlingTest, InvalidScanScript6) { 664 uint8_t* buffer = nullptr; 665 unsigned long buffer_size = 0; // NOLINT 666 jpeg_compress_struct cinfo; 667 const auto try_catch_block = [&]() -> bool { 668 ERROR_HANDLER_SETUP(jpegli); 669 jpegli_create_compress(&cinfo); 670 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 671 cinfo.image_width = 1; 672 cinfo.image_height = 1; 673 cinfo.input_components = 1; 674 jpegli_set_defaults(&cinfo); 675 static constexpr jpeg_scan_info kScript[] = {{1, {0}, 0, 64, 0, 0}}; // 676 cinfo.scan_info = kScript; 677 cinfo.num_scans = ARRAY_SIZE(kScript); 678 jpegli_start_compress(&cinfo, TRUE); 679 return true; 680 }; 681 EXPECT_FALSE(try_catch_block()); 682 jpegli_destroy_compress(&cinfo); 683 if (buffer) free(buffer); 684 } 685 686 TEST(EncoderErrorHandlingTest, InvalidScanScript7) { 687 uint8_t* buffer = nullptr; 688 unsigned long buffer_size = 0; // NOLINT 689 jpeg_compress_struct cinfo; 690 const auto try_catch_block = [&]() -> bool { 691 ERROR_HANDLER_SETUP(jpegli); 692 jpegli_create_compress(&cinfo); 693 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 694 cinfo.image_width = 1; 695 cinfo.image_height = 1; 696 cinfo.input_components = 1; 697 jpegli_set_defaults(&cinfo); 698 static constexpr jpeg_scan_info kScript[] = {{1, {0}, 2, 1, 0, 0}}; // 699 cinfo.scan_info = kScript; 700 cinfo.num_scans = ARRAY_SIZE(kScript); 701 jpegli_start_compress(&cinfo, TRUE); 702 return true; 703 }; 704 EXPECT_FALSE(try_catch_block()); 705 jpegli_destroy_compress(&cinfo); 706 if (buffer) free(buffer); 707 } 708 709 TEST(EncoderErrorHandlingTest, InvalidScanScript8) { 710 uint8_t* buffer = nullptr; 711 unsigned long buffer_size = 0; // NOLINT 712 jpeg_compress_struct cinfo; 713 const auto try_catch_block = [&]() -> bool { 714 ERROR_HANDLER_SETUP(jpegli); 715 jpegli_create_compress(&cinfo); 716 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 717 cinfo.image_width = 1; 718 cinfo.image_height = 1; 719 cinfo.input_components = 2; 720 jpegli_set_defaults(&cinfo); 721 static constexpr jpeg_scan_info kScript[] = { 722 {1, {0}, 0, 63, 0, 0}, {1, {1}, 0, 0, 0, 0}, {1, {1}, 1, 63, 0, 0} // 723 }; 724 cinfo.scan_info = kScript; 725 cinfo.num_scans = ARRAY_SIZE(kScript); 726 jpegli_start_compress(&cinfo, TRUE); 727 return true; 728 }; 729 EXPECT_FALSE(try_catch_block()); 730 jpegli_destroy_compress(&cinfo); 731 if (buffer) free(buffer); 732 } 733 734 TEST(EncoderErrorHandlingTest, InvalidScanScript9) { 735 uint8_t* buffer = nullptr; 736 unsigned long buffer_size = 0; // NOLINT 737 jpeg_compress_struct cinfo; 738 const auto try_catch_block = [&]() -> bool { 739 ERROR_HANDLER_SETUP(jpegli); 740 jpegli_create_compress(&cinfo); 741 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 742 cinfo.image_width = 1; 743 cinfo.image_height = 1; 744 cinfo.input_components = 1; 745 jpegli_set_defaults(&cinfo); 746 static constexpr jpeg_scan_info kScript[] = { 747 {1, {0}, 0, 1, 0, 0}, {1, {0}, 2, 63, 0, 0}, // 748 }; 749 cinfo.scan_info = kScript; 750 cinfo.num_scans = ARRAY_SIZE(kScript); 751 jpegli_start_compress(&cinfo, TRUE); 752 return true; 753 }; 754 EXPECT_FALSE(try_catch_block()); 755 jpegli_destroy_compress(&cinfo); 756 if (buffer) free(buffer); 757 } 758 759 TEST(EncoderErrorHandlingTest, InvalidScanScript10) { 760 uint8_t* buffer = nullptr; 761 unsigned long buffer_size = 0; // NOLINT 762 jpeg_compress_struct cinfo; 763 const auto try_catch_block = [&]() -> bool { 764 ERROR_HANDLER_SETUP(jpegli); 765 jpegli_create_compress(&cinfo); 766 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 767 cinfo.image_width = 1; 768 cinfo.image_height = 1; 769 cinfo.input_components = 2; 770 jpegli_set_defaults(&cinfo); 771 static constexpr jpeg_scan_info kScript[] = { 772 {2, {0, 1}, 0, 0, 0, 0}, {2, {0, 1}, 1, 63, 0, 0} // 773 }; 774 cinfo.scan_info = kScript; 775 cinfo.num_scans = ARRAY_SIZE(kScript); 776 jpegli_start_compress(&cinfo, TRUE); 777 return true; 778 }; 779 EXPECT_FALSE(try_catch_block()); 780 jpegli_destroy_compress(&cinfo); 781 if (buffer) free(buffer); 782 } 783 784 TEST(EncoderErrorHandlingTest, InvalidScanScript11) { 785 uint8_t* buffer = nullptr; 786 unsigned long buffer_size = 0; // NOLINT 787 jpeg_compress_struct cinfo; 788 const auto try_catch_block = [&]() -> bool { 789 ERROR_HANDLER_SETUP(jpegli); 790 jpegli_create_compress(&cinfo); 791 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 792 cinfo.image_width = 1; 793 cinfo.image_height = 1; 794 cinfo.input_components = 1; 795 jpegli_set_defaults(&cinfo); 796 static constexpr jpeg_scan_info kScript[] = { 797 {1, {0}, 1, 63, 0, 0}, {1, {0}, 0, 0, 0, 0} // 798 }; 799 cinfo.scan_info = kScript; 800 cinfo.num_scans = ARRAY_SIZE(kScript); 801 jpegli_start_compress(&cinfo, TRUE); 802 return true; 803 }; 804 EXPECT_FALSE(try_catch_block()); 805 jpegli_destroy_compress(&cinfo); 806 if (buffer) free(buffer); 807 } 808 809 TEST(EncoderErrorHandlingTest, InvalidScanScript12) { 810 uint8_t* buffer = nullptr; 811 unsigned long buffer_size = 0; // NOLINT 812 jpeg_compress_struct cinfo; 813 const auto try_catch_block = [&]() -> bool { 814 ERROR_HANDLER_SETUP(jpegli); 815 jpegli_create_compress(&cinfo); 816 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 817 cinfo.image_width = 1; 818 cinfo.image_height = 1; 819 cinfo.input_components = 1; 820 jpegli_set_defaults(&cinfo); 821 static constexpr jpeg_scan_info kScript[] = { 822 {1, {0}, 0, 0, 10, 1}, {1, {0}, 0, 0, 1, 0}, {1, {0}, 1, 63, 0, 0} // 823 }; 824 cinfo.scan_info = kScript; 825 cinfo.num_scans = ARRAY_SIZE(kScript); 826 jpegli_start_compress(&cinfo, TRUE); 827 return true; 828 }; 829 EXPECT_FALSE(try_catch_block()); 830 jpegli_destroy_compress(&cinfo); 831 if (buffer) free(buffer); 832 } 833 834 TEST(EncoderErrorHandlingTest, InvalidScanScript13) { 835 uint8_t* buffer = nullptr; 836 unsigned long buffer_size = 0; // NOLINT 837 jpeg_compress_struct cinfo; 838 const auto try_catch_block = [&]() -> bool { 839 ERROR_HANDLER_SETUP(jpegli); 840 jpegli_create_compress(&cinfo); 841 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 842 cinfo.image_width = 1; 843 cinfo.image_height = 1; 844 cinfo.input_components = 1; 845 jpegli_set_defaults(&cinfo); 846 static constexpr jpeg_scan_info kScript[] = { 847 {1, {0}, 0, 0, 0, 2}, 848 {1, {0}, 0, 0, 1, 0}, 849 {1, {0}, 0, 0, 2, 1}, // 850 {1, {0}, 1, 63, 0, 0} // 851 }; 852 cinfo.scan_info = kScript; 853 cinfo.num_scans = ARRAY_SIZE(kScript); 854 jpegli_start_compress(&cinfo, TRUE); 855 return true; 856 }; 857 EXPECT_FALSE(try_catch_block()); 858 jpegli_destroy_compress(&cinfo); 859 if (buffer) free(buffer); 860 } 861 862 TEST(EncoderErrorHandlingTest, MCUSizeTooBig) { 863 uint8_t* buffer = nullptr; 864 unsigned long buffer_size = 0; // NOLINT 865 jpeg_compress_struct cinfo; 866 const auto try_catch_block = [&]() -> bool { 867 ERROR_HANDLER_SETUP(jpegli); 868 jpegli_create_compress(&cinfo); 869 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 870 cinfo.image_width = 1; 871 cinfo.image_height = 1; 872 cinfo.input_components = 3; 873 jpegli_set_defaults(&cinfo); 874 jpegli_set_progressive_level(&cinfo, 0); 875 cinfo.comp_info[0].h_samp_factor = 3; 876 cinfo.comp_info[0].v_samp_factor = 3; 877 jpegli_start_compress(&cinfo, TRUE); 878 return true; 879 }; 880 EXPECT_FALSE(try_catch_block()); 881 jpegli_destroy_compress(&cinfo); 882 if (buffer) free(buffer); 883 } 884 885 TEST(EncoderErrorHandlingTest, RestartIntervalTooBig) { 886 uint8_t* buffer = nullptr; 887 unsigned long buffer_size = 0; // NOLINT 888 jpeg_compress_struct cinfo; 889 const auto try_catch_block = [&]() -> bool { 890 ERROR_HANDLER_SETUP(jpegli); 891 jpegli_create_compress(&cinfo); 892 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 893 cinfo.image_width = 1; 894 cinfo.image_height = 1; 895 cinfo.input_components = 1; 896 jpegli_set_defaults(&cinfo); 897 cinfo.restart_interval = 1000000; 898 jpegli_start_compress(&cinfo, TRUE); 899 return true; 900 }; 901 EXPECT_FALSE(try_catch_block()); 902 jpegli_destroy_compress(&cinfo); 903 if (buffer) free(buffer); 904 } 905 906 TEST(EncoderErrorHandlingTest, SamplingFactorTooBig) { 907 uint8_t* buffer = nullptr; 908 unsigned long buffer_size = 0; // NOLINT 909 jpeg_compress_struct cinfo; 910 const auto try_catch_block = [&]() -> bool { 911 ERROR_HANDLER_SETUP(jpegli); 912 jpegli_create_compress(&cinfo); 913 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 914 cinfo.image_width = 1; 915 cinfo.image_height = 1; 916 cinfo.input_components = 3; 917 jpegli_set_defaults(&cinfo); 918 cinfo.comp_info[0].h_samp_factor = 5; 919 jpegli_start_compress(&cinfo, TRUE); 920 return true; 921 }; 922 EXPECT_FALSE(try_catch_block()); 923 jpegli_destroy_compress(&cinfo); 924 if (buffer) free(buffer); 925 } 926 927 TEST(EncoderErrorHandlingTest, NonIntegralSamplingRatio) { 928 uint8_t* buffer = nullptr; 929 unsigned long buffer_size = 0; // NOLINT 930 jpeg_compress_struct cinfo; 931 const auto try_catch_block = [&]() -> bool { 932 ERROR_HANDLER_SETUP(jpegli); 933 jpegli_create_compress(&cinfo); 934 jpegli_mem_dest(&cinfo, &buffer, &buffer_size); 935 cinfo.image_width = 1; 936 cinfo.image_height = 1; 937 cinfo.input_components = 3; 938 jpegli_set_defaults(&cinfo); 939 cinfo.comp_info[0].h_samp_factor = 3; 940 cinfo.comp_info[1].h_samp_factor = 2; 941 jpegli_start_compress(&cinfo, TRUE); 942 return true; 943 }; 944 EXPECT_FALSE(try_catch_block()); 945 jpegli_destroy_compress(&cinfo); 946 if (buffer) free(buffer); 947 } 948 949 constexpr const char* kAddOnTable[] = {"First message", 950 "Second message with int param %d", 951 "Third message with string param %s"}; 952 953 TEST(EncoderErrorHandlingTest, AddOnTableNoParam) { 954 jpeg_compress_struct cinfo; 955 const auto try_catch_block = [&]() -> bool { 956 ERROR_HANDLER_SETUP(jpegli); 957 jpegli_create_compress(&cinfo); 958 cinfo.err->addon_message_table = kAddOnTable; 959 cinfo.err->first_addon_message = 10000; 960 cinfo.err->last_addon_message = 10002; 961 cinfo.err->msg_code = 10000; 962 (*cinfo.err->error_exit)(reinterpret_cast<j_common_ptr>(&cinfo)); 963 return true; 964 }; 965 EXPECT_FALSE(try_catch_block()); 966 jpegli_destroy_compress(&cinfo); 967 } 968 969 TEST(EncoderErrorHandlingTest, AddOnTableIntParam) { 970 jpeg_compress_struct cinfo; 971 const auto try_catch_block = [&]() -> bool { 972 ERROR_HANDLER_SETUP(jpegli); 973 jpegli_create_compress(&cinfo); 974 cinfo.err->addon_message_table = kAddOnTable; 975 cinfo.err->first_addon_message = 10000; 976 cinfo.err->last_addon_message = 10002; 977 cinfo.err->msg_code = 10001; 978 cinfo.err->msg_parm.i[0] = 17; 979 (*cinfo.err->error_exit)(reinterpret_cast<j_common_ptr>(&cinfo)); 980 return true; 981 }; 982 EXPECT_FALSE(try_catch_block()); 983 jpegli_destroy_compress(&cinfo); 984 } 985 986 TEST(EncoderErrorHandlingTest, AddOnTableNoStringParam) { 987 jpeg_compress_struct cinfo; 988 const auto try_catch_block = [&]() -> bool { 989 ERROR_HANDLER_SETUP(jpegli); 990 jpegli_create_compress(&cinfo); 991 cinfo.err->addon_message_table = kAddOnTable; 992 cinfo.err->first_addon_message = 10000; 993 cinfo.err->last_addon_message = 10002; 994 cinfo.err->msg_code = 10002; 995 memcpy(cinfo.err->msg_parm.s, "MESSAGE PARAM", 14); 996 (*cinfo.err->error_exit)(reinterpret_cast<j_common_ptr>(&cinfo)); 997 return true; 998 }; 999 EXPECT_FALSE(try_catch_block()); 1000 jpegli_destroy_compress(&cinfo); 1001 } 1002 1003 const uint8_t kCompressed0[] = { 1004 // SOI 1005 0xff, 0xd8, // 1006 // SOF 1007 0xff, 0xc0, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01, 0x01, // 1008 0x01, 0x11, 0x00, // 1009 // DQT 1010 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x03, 0x02, // 1011 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x05, // 1012 0x08, 0x05, 0x05, 0x04, 0x04, 0x05, 0x0a, 0x07, 0x07, 0x06, // 1013 0x08, 0x0c, 0x0a, 0x0c, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, 0x0d, // 1014 0x0e, 0x12, 0x10, 0x0d, 0x0e, 0x11, 0x0e, 0x0b, 0x0b, 0x10, // 1015 0x16, 0x10, 0x11, 0x13, 0x14, 0x15, 0x15, 0x15, 0x0c, 0x0f, // 1016 0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, // 1017 // DHT 1018 0xff, 0xc4, 0x00, 0xd2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, // 1019 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1020 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 1021 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, // 1022 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, // 1023 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, // 1024 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, // 1025 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, // 1026 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, // 1027 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, // 1028 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, // 1029 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, // 1030 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, // 1031 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, // 1032 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, // 1033 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, // 1034 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, // 1035 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, // 1036 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, // 1037 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, // 1038 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, // 1039 0xf9, 0xfa, // 1040 // SOS 1041 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, // 1042 // entropy coded data 1043 0xfc, 0xaa, 0xaf, // 1044 // EOI 1045 0xff, 0xd9, // 1046 }; 1047 const size_t kLen0 = sizeof(kCompressed0); 1048 1049 const size_t kSOFOffset = 2; 1050 const size_t kDQTOffset = 15; 1051 const size_t kDHTOffset = 84; 1052 const size_t kSOSOffset = 296; 1053 1054 TEST(DecoderErrorHandlingTest, MinimalSuccess) { 1055 ASSERT_TRUE(kCompressed0[kDQTOffset] == 0xff); 1056 ASSERT_TRUE(kCompressed0[kSOFOffset] == 0xff); 1057 ASSERT_TRUE(kCompressed0[kDHTOffset] == 0xff); 1058 ASSERT_TRUE(kCompressed0[kSOSOffset] == 0xff); 1059 jpeg_decompress_struct cinfo = {}; 1060 const auto try_catch_block = [&]() -> bool { 1061 ERROR_HANDLER_SETUP(jpegli); 1062 jpegli_create_decompress(&cinfo); 1063 jpegli_mem_src(&cinfo, kCompressed0, kLen0); 1064 jpegli_read_header(&cinfo, TRUE); 1065 EXPECT_EQ(1, cinfo.image_width); 1066 EXPECT_EQ(1, cinfo.image_height); 1067 jpegli_start_decompress(&cinfo); 1068 JSAMPLE image[1]; 1069 JSAMPROW row[] = {image}; 1070 jpegli_read_scanlines(&cinfo, row, 1); 1071 EXPECT_EQ(0, image[0]); 1072 jpegli_finish_decompress(&cinfo); 1073 return true; 1074 }; 1075 EXPECT_TRUE(try_catch_block()); 1076 jpegli_destroy_decompress(&cinfo); 1077 } 1078 1079 TEST(DecoderErrorHandlingTest, NoSource) { 1080 jpeg_decompress_struct cinfo = {}; 1081 const auto try_catch_block = [&]() -> bool { 1082 ERROR_HANDLER_SETUP(jpegli); 1083 jpegli_create_decompress(&cinfo); 1084 jpegli_read_header(&cinfo, TRUE); 1085 return true; 1086 }; 1087 EXPECT_FALSE(try_catch_block()); 1088 jpegli_destroy_decompress(&cinfo); 1089 } 1090 1091 TEST(DecoderErrorHandlingTest, NoReadHeader) { 1092 jpeg_decompress_struct cinfo = {}; 1093 const auto try_catch_block = [&]() -> bool { 1094 ERROR_HANDLER_SETUP(jpegli); 1095 jpegli_create_decompress(&cinfo); 1096 jpegli_mem_src(&cinfo, kCompressed0, kLen0); 1097 jpegli_start_decompress(&cinfo); 1098 return true; 1099 }; 1100 EXPECT_FALSE(try_catch_block()); 1101 jpegli_destroy_decompress(&cinfo); 1102 } 1103 1104 TEST(DecoderErrorHandlingTest, NoStartDecompress) { 1105 jpeg_decompress_struct cinfo = {}; 1106 const auto try_catch_block = [&]() -> bool { 1107 ERROR_HANDLER_SETUP(jpegli); 1108 jpegli_create_decompress(&cinfo); 1109 jpegli_mem_src(&cinfo, kCompressed0, kLen0); 1110 jpegli_read_header(&cinfo, TRUE); 1111 EXPECT_EQ(1, cinfo.image_width); 1112 EXPECT_EQ(1, cinfo.image_height); 1113 JSAMPLE image[1]; 1114 JSAMPROW row[] = {image}; 1115 jpegli_read_scanlines(&cinfo, row, 1); 1116 EXPECT_EQ(0, image[0]); 1117 jpegli_finish_decompress(&cinfo); 1118 return true; 1119 }; 1120 EXPECT_FALSE(try_catch_block()); 1121 jpegli_destroy_decompress(&cinfo); 1122 } 1123 1124 TEST(DecoderErrorHandlingTest, NoReadScanlines) { 1125 jpeg_decompress_struct cinfo = {}; 1126 const auto try_catch_block = [&]() -> bool { 1127 ERROR_HANDLER_SETUP(jpegli); 1128 jpegli_create_decompress(&cinfo); 1129 jpegli_mem_src(&cinfo, kCompressed0, kLen0); 1130 jpegli_read_header(&cinfo, TRUE); 1131 EXPECT_EQ(1, cinfo.image_width); 1132 EXPECT_EQ(1, cinfo.image_height); 1133 jpegli_start_decompress(&cinfo); 1134 jpegli_finish_decompress(&cinfo); 1135 return true; 1136 }; 1137 EXPECT_FALSE(try_catch_block()); 1138 jpegli_destroy_decompress(&cinfo); 1139 } 1140 1141 const size_t kMaxImageWidth = 0xffff; 1142 JSAMPLE kOutputBuffer[MAX_COMPONENTS * kMaxImageWidth]; 1143 1144 bool ParseCompressed(const std::vector<uint8_t>& compressed) { 1145 jpeg_decompress_struct cinfo = {}; 1146 const auto try_catch_block = [&]() -> bool { 1147 ERROR_HANDLER_SETUP(jpegli); 1148 jpegli_create_decompress(&cinfo); 1149 jpegli_mem_src(&cinfo, compressed.data(), compressed.size()); 1150 jpegli_read_header(&cinfo, TRUE); 1151 jpegli_start_decompress(&cinfo); 1152 for (JDIMENSION i = 0; i < cinfo.output_height; ++i) { 1153 JSAMPROW row[] = {kOutputBuffer}; 1154 jpegli_read_scanlines(&cinfo, row, 1); 1155 } 1156 jpegli_finish_decompress(&cinfo); 1157 return true; 1158 }; 1159 bool retval = try_catch_block(); 1160 jpegli_destroy_decompress(&cinfo); 1161 return retval; 1162 } 1163 1164 TEST(DecoderErrorHandlingTest, NoSOI) { 1165 for (int pos : {0, 1}) { 1166 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1167 compressed[pos] = 0; 1168 EXPECT_FALSE(ParseCompressed(compressed)); 1169 } 1170 } 1171 1172 TEST(DecoderErrorHandlingTest, InvalidDQT) { 1173 // Bad marker length 1174 for (int diff : {-2, -1, 1, 2}) { 1175 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1176 compressed[kDQTOffset + 3] += diff; 1177 EXPECT_FALSE(ParseCompressed(compressed)); 1178 } 1179 // invalid table index / precision 1180 for (int val : {0x20, 0x05}) { 1181 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1182 compressed[kDQTOffset + 4] = val; 1183 EXPECT_FALSE(ParseCompressed(compressed)); 1184 } 1185 // zero quant value 1186 for (int k : {0, 1, 17, 63}) { 1187 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1188 compressed[kDQTOffset + 5 + k] = 0; 1189 EXPECT_FALSE(ParseCompressed(compressed)); 1190 } 1191 } 1192 1193 TEST(DecoderErrorHandlingTest, InvalidSOF) { 1194 // Bad marker length 1195 for (int diff : {-2, -1, 1, 2}) { 1196 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1197 compressed[kSOFOffset + 3] += diff; 1198 EXPECT_FALSE(ParseCompressed(compressed)); 1199 } 1200 // zero width, height or num_components 1201 for (int pos : {6, 8, 9}) { 1202 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1203 compressed[kSOFOffset + pos] = 0; 1204 EXPECT_FALSE(ParseCompressed(compressed)); 1205 } 1206 // invalid data precision 1207 for (int val : {0, 1, 127}) { 1208 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1209 compressed[kSOFOffset + 4] = val; 1210 EXPECT_FALSE(ParseCompressed(compressed)); 1211 } 1212 // too many num_components 1213 for (int val : {5, 255}) { 1214 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1215 compressed[kSOFOffset + 9] = val; 1216 EXPECT_FALSE(ParseCompressed(compressed)); 1217 } 1218 // invalid sampling factors 1219 for (int val : {0x00, 0x01, 0x10, 0x15, 0x51}) { 1220 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1221 compressed[kSOFOffset + 11] = val; 1222 EXPECT_FALSE(ParseCompressed(compressed)); 1223 } 1224 // invalid quant table index 1225 for (int val : {5, 17}) { 1226 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1227 compressed[kSOFOffset + 12] = val; 1228 EXPECT_FALSE(ParseCompressed(compressed)); 1229 } 1230 } 1231 1232 TEST(DecoderErrorHandlingTest, InvalidDHT) { 1233 // Bad marker length 1234 for (int diff : {-2, -1, 1, 2}) { 1235 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1236 compressed[kDHTOffset + 3] += diff; 1237 EXPECT_FALSE(ParseCompressed(compressed)); 1238 } 1239 { 1240 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1241 compressed[kDHTOffset + 2] += 17; 1242 EXPECT_FALSE(ParseCompressed(compressed)); 1243 } 1244 // invalid table slot_id 1245 for (int val : {0x05, 0x15, 0x20}) { 1246 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1247 compressed[kDHTOffset + 4] = val; 1248 EXPECT_FALSE(ParseCompressed(compressed)); 1249 } 1250 } 1251 1252 TEST(DecoderErrorHandlingTest, InvalidSOS) { 1253 // Invalid comps_in_scan 1254 for (int val : {2, 5, 17}) { 1255 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1256 compressed[kSOSOffset + 4] = val; 1257 EXPECT_FALSE(ParseCompressed(compressed)); 1258 } 1259 // invalid Huffman table indexes 1260 for (int val : {0x05, 0x50, 0x15, 0x51}) { 1261 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1262 compressed[kSOSOffset + 6] = val; 1263 EXPECT_FALSE(ParseCompressed(compressed)); 1264 } 1265 // invalid Ss/Se 1266 for (int pos : {7, 8}) { 1267 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1268 compressed[kSOSOffset + pos] = 64; 1269 EXPECT_FALSE(ParseCompressed(compressed)); 1270 } 1271 } 1272 1273 TEST(DecoderErrorHandlingTest, MutateSingleBytes) { 1274 for (size_t pos = 0; pos < kLen0; ++pos) { 1275 std::vector<uint8_t> compressed(kCompressed0, kCompressed0 + kLen0); 1276 for (int val : {0x00, 0x0f, 0xf0, 0xff}) { 1277 compressed[pos] = val; 1278 ParseCompressed(compressed); 1279 } 1280 } 1281 } 1282 1283 } // namespace 1284 } // namespace jpegli