require 3 or 4 B2A output channels
We'd been requiring 1-4 in one place and 0-4 in another,
while asserting it was 3-4 in the CLUT transform code.
This should make everyone agree on 3-4.
Add a profile with 2 output mBA tag,
which we should now fail to parse.
Bug: oss-fuzz:33281
Change-Id: Ia9db10805e4b046dc4adf112e7f8679c0e6b96c3
Reviewed-on: https://skia-review.googlesource.com/c/skcms/+/397075
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/profiles/fuzz/b2a_too_few_output_channels.icc b/profiles/fuzz/b2a_too_few_output_channels.icc
new file mode 100644
index 0000000..b757b03
--- /dev/null
+++ b/profiles/fuzz/b2a_too_few_output_channels.icc
Binary files differ
diff --git a/profiles/fuzz/b2a_too_few_output_channels.icc.txt b/profiles/fuzz/b2a_too_few_output_channels.icc.txt
new file mode 100644
index 0000000..979baac
--- /dev/null
+++ b/profiles/fuzz/b2a_too_few_output_channels.icc.txt
@@ -0,0 +1 @@
+Unable to parse ICC profile
diff --git a/skcms.cc b/skcms.cc
index 21e1c83..0b2c781 100644
--- a/skcms.cc
+++ b/skcms.cc
@@ -636,11 +636,11 @@
b2a->output_channels = mftTag->output_channels[0];
- // For B2A, exactly 3 *input* channels and 1-4 *output* channels.
+ // For B2A, exactly 3 input channels (XYZ) and 3 (RGB) or 4 (CMYK) output channels.
if (b2a->input_channels != ARRAY_COUNT(b2a->input_curves)) {
return false;
}
- if (b2a->output_channels < 1 || b2a->output_channels > ARRAY_COUNT(b2a->output_curves)) {
+ if (b2a->output_channels < 3 || b2a->output_channels > ARRAY_COUNT(b2a->output_curves)) {
return false;
}
@@ -936,11 +936,11 @@
b2a->input_channels = mBATag->input_channels[0];
b2a->output_channels = mBATag->output_channels[0];
- // Input and output arity requirements swapped... |inputs|==3, |outputs|<=4.
+ // Require exactly 3 inputs (XYZ) and 3 (RGB) or 4 (CMYK) outputs.
if (b2a->input_channels != ARRAY_COUNT(b2a->input_curves)) {
return false;
}
- if (b2a->output_channels > ARRAY_COUNT(b2a->output_curves)) {
+ if (b2a->output_channels < 3 || b2a->output_channels > ARRAY_COUNT(b2a->output_curves)) {
return false;
}
@@ -964,7 +964,7 @@
if (0 == matrix_offset) {
return false;
}
- // Matrix channels is tied to input_channels (3), not output_channels (1-4).
+ // Matrix channels is tied to input_channels (3), not output_channels.
b2a->matrix_channels = b2a->input_channels;
if (!read_curves(tag->buf, tag->size, m_curve_offset, b2a->matrix_channels,
diff --git a/tests.c b/tests.c
index de44d1d..e6bc1fc 100644
--- a/tests.c
+++ b/tests.c
@@ -650,6 +650,7 @@
"profiles/fuzz/a2b_too_many_input_channels2.icc", // oss-fuzz:32765
"profiles/fuzz/mangled_trc_tags.icc", // chromium:835666
"profiles/fuzz/negative_g_para.icc", // chromium:836634
+ "profiles/fuzz/b2a_too_few_output_channels.icc", // oss-fuzz:33281
// Caused skcms_PolyTF fit to round trip indices outside the range of int.
"profiles/fuzz/infinite_roundtrip.icc", // oss-fuzz:8101