Skip to content

Commit bb6cd56

Browse files
yungstersfacebook-github-bot
authored andcommitted
RN: Fallback for Invalid Colors in processColorArray
Summary: If an invalid color is supplied to a native component that expects `Array<ColorValue>`, it is currently possible to produce an array that contains null or undefined elements. This is problematic because the native component may not know what to do with the null or undefined value. This changes `processColorArray` to always return an array with valid color values. Any invalid color values will fallback to being transparent black, `0x00000000`. Changelog: [General][Fixed] - For native components that accept color arrays, invalid elements will now fallback to transparent with a console error. Reviewed By: JoshuaGross Differential Revision: D27542291 fbshipit-source-id: efa5d130644b3aee68d2b9fad6fdb61af11a2966
1 parent 322e8f7 commit bb6cd56

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

Libraries/StyleSheet/__tests__/processColorArray-test.js

+25-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const PlatformColorAndroid = require('../PlatformColorValueTypes.android')
2222

2323
const platformSpecific =
2424
OS === 'android'
25-
? unsigned => unsigned | 0 //eslint-disable-line no-bitwise
25+
? unsigned => unsigned | 0 // eslint-disable-line no-bitwise
2626
: x => x;
2727

2828
describe('processColorArray', () => {
@@ -63,6 +63,30 @@ describe('processColorArray', () => {
6363
const colorFromNoArray = processColorArray(null);
6464
expect(colorFromNoArray).toEqual(null);
6565
});
66+
67+
it('converts invalid colors to transparent', () => {
68+
const spy = jest.spyOn(console, 'error').mockReturnValue(undefined);
69+
70+
const colors = ['red', '???', null, undefined, false];
71+
const colorFromStringArray = processColorArray(colors);
72+
const expectedIntArray = [
73+
0xffff0000,
74+
0x00000000,
75+
0x00000000,
76+
0x00000000,
77+
0x00000000,
78+
].map(platformSpecific);
79+
expect(colorFromStringArray).toEqual(expectedIntArray);
80+
81+
for (const color of colors.slice(1)) {
82+
expect(spy).toHaveBeenCalledWith(
83+
'Invalid value in color array:',
84+
color,
85+
);
86+
}
87+
88+
spy.mockRestore();
89+
});
6690
});
6791

6892
describe('iOS', () => {

Libraries/StyleSheet/processColorArray.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,25 @@
1010

1111
'use strict';
1212

13-
const processColor = require('./processColor');
14-
1513
import type {ColorValue} from './StyleSheet';
16-
import type {ProcessedColorValue} from './processColor';
14+
import processColor, {type ProcessedColorValue} from './processColor';
15+
16+
const TRANSPARENT = 0; // rgba(0, 0, 0, 0)
1717

1818
function processColorArray(
19-
colors: ?Array<ColorValue>,
20-
): ?Array<?ProcessedColorValue> {
21-
return colors == null ? null : colors.map(processColor);
19+
colors: ?$ReadOnlyArray<ColorValue>,
20+
): ?$ReadOnlyArray<ProcessedColorValue> {
21+
return colors == null ? null : colors.map(processColorElement);
22+
}
23+
24+
function processColorElement(color: ColorValue): ProcessedColorValue {
25+
const value = processColor(color);
26+
// For invalid colors, fallback to transparent.
27+
if (value == null) {
28+
console.error('Invalid value in color array:', color);
29+
return TRANSPARENT;
30+
}
31+
return value;
2232
}
2333

2434
module.exports = processColorArray;

0 commit comments

Comments
 (0)