From 8e2de303e329e29728843dce4ff81177efca0a7a Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 28 Jan 2025 22:47:40 -0800 Subject: [PATCH] Disallow invalid unitless lengths in box shadows (#48988) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/48988 The only unitless `` value allowed is `0`, so most of the examples in the `processBoxShadow` unit tests are parse errors on web 🫠. Lets update the tests, and disallow these invalid values. Changelog: [General][Breaking] - Disallow invalid unitless lengths in box shadows Reviewed By: jorge-cab Differential Revision: D68740553 fbshipit-source-id: ea935819f773c5d516dd9b3367e5d2c808941c28 --- .../__tests__/processBoxShadow-test.js | 55 ++++++++++++------- .../Libraries/StyleSheet/processBoxShadow.js | 4 ++ 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/packages/react-native/Libraries/StyleSheet/__tests__/processBoxShadow-test.js b/packages/react-native/Libraries/StyleSheet/__tests__/processBoxShadow-test.js index 1700aaba8b4..4ff5f25b8c5 100644 --- a/packages/react-native/Libraries/StyleSheet/__tests__/processBoxShadow-test.js +++ b/packages/react-native/Libraries/StyleSheet/__tests__/processBoxShadow-test.js @@ -15,7 +15,7 @@ import processColor from '../processColor'; // js1 test processBoxShadow describe('processBoxShadow', () => { it('should parse basic string', () => { - expect(processBoxShadow('10px 5')).toEqual([ + expect(processBoxShadow('10px 5px')).toEqual([ { offsetX: 10, offsetY: 5, @@ -23,8 +23,17 @@ describe('processBoxShadow', () => { ]); }); + it('should parse basic string with unitless zero length', () => { + expect(processBoxShadow('10px 0')).toEqual([ + { + offsetX: 10, + offsetY: 0, + }, + ]); + }); + it('should parse basic string with multiple whitespaces', () => { - expect(processBoxShadow('10px 5')).toEqual([ + expect(processBoxShadow('10px 5px')).toEqual([ { offsetX: 10, offsetY: 5, @@ -33,7 +42,7 @@ describe('processBoxShadow', () => { }); it('should parse string with color', () => { - expect(processBoxShadow('red 10 5')).toEqual([ + expect(processBoxShadow('red 10px 5px')).toEqual([ { color: processColor('red'), offsetX: 10, @@ -43,7 +52,7 @@ describe('processBoxShadow', () => { }); it('should parse string with color function rgba', () => { - expect(processBoxShadow('rgba(255, 255, 255, 0.5) 10 5')).toEqual([ + expect(processBoxShadow('rgba(255, 255, 255, 0.5) 10px 5px')).toEqual([ { color: processColor('rgba(255, 255, 255, 0.5)'), offsetX: 10, @@ -53,7 +62,7 @@ describe('processBoxShadow', () => { }); it('should parse string with color function hsl', () => { - expect(processBoxShadow('hsl(318, 69%, 55%) 10 5')).toEqual([ + expect(processBoxShadow('hsl(318, 69%, 55%) 10px 5px')).toEqual([ { color: processColor('hsl(318, 69%, 55%)'), offsetX: 10, @@ -63,7 +72,7 @@ describe('processBoxShadow', () => { }); it('should parse string with hex color', () => { - expect(processBoxShadow('#FFFFFF 10 5')).toEqual([ + expect(processBoxShadow('#FFFFFF 10px 5px')).toEqual([ { color: processColor('#FFFFFF'), offsetX: 10, @@ -73,7 +82,7 @@ describe('processBoxShadow', () => { }); it('should parse string with blurRadius', () => { - expect(processBoxShadow('red 10 5 2')).toEqual([ + expect(processBoxShadow('red 10px 5px 2px')).toEqual([ { color: processColor('red'), blurRadius: 2, @@ -84,7 +93,7 @@ describe('processBoxShadow', () => { }); it('should parse string with spreadDistance', () => { - expect(processBoxShadow('red 10 5 2 3')).toEqual([ + expect(processBoxShadow('red 10px 5px 2px 3px')).toEqual([ { color: processColor('red'), blurRadius: 2, @@ -115,7 +124,7 @@ describe('processBoxShadow', () => { }); it('should parse string with inset and color before and after lengths', () => { - expect(processBoxShadow('red 10 10 inset')).toEqual([ + expect(processBoxShadow('red 10px 10px inset')).toEqual([ { color: processColor('red'), offsetX: 10, @@ -127,7 +136,9 @@ describe('processBoxShadow', () => { it('should parse multiple box shadow strings', () => { expect( - processBoxShadow('10 5 red, 5 12 inset, inset 10 45 13 red'), + processBoxShadow( + '10px 5px red, 5px 12px inset, inset 10px 45px 13px red', + ), ).toEqual([ { offsetX: 10, @@ -151,7 +162,9 @@ describe('processBoxShadow', () => { it('should parse multiple box shadow strings with newlines', () => { expect( - processBoxShadow('10 5 red, 5 12 inset,\n inset 10 45 13 red'), + processBoxShadow( + '10px 5px red, 5px 12px inset,\n inset 10px 45px 13px red', + ), ).toEqual([ { offsetX: 10, @@ -178,35 +191,39 @@ describe('processBoxShadow', () => { }); it('should fail to parse too many lengths', () => { - expect(processBoxShadow('10 5 2 3 10 10')).toEqual([]); + expect(processBoxShadow('10px 5px 2px 3px 10px 10px')).toEqual([]); }); it('should fail to parse inset between lengths', () => { - expect(processBoxShadow('10 inset 5 2 3,')).toEqual([]); + expect(processBoxShadow('10px inset 5px 2px 3px,')).toEqual([]); }); it('should fail to parse double color', () => { - expect(processBoxShadow('red red 10 5')).toEqual([]); + expect(processBoxShadow('red red 10px 5px')).toEqual([]); }); it('should fail to parse double inset', () => { - expect(processBoxShadow('10 5 inset inset')).toEqual([]); + expect(processBoxShadow('10px 5px inset inset')).toEqual([]); }); it('should fail to parse color between lengths', () => { - expect(processBoxShadow('10 red 5 2 3,')).toEqual([]); + expect(processBoxShadow('10px red 5px 2px 3px,')).toEqual([]); }); it('should fail to parse invalid unit', () => { - expect(processBoxShadow('red 10foo 5 2 3,')).toEqual([]); + expect(processBoxShadow('red 10foo 5px 2px 3px,')).toEqual([]); }); it('should fail to parse invalid argument', () => { - expect(processBoxShadow('red asf 5 2 3')).toEqual([]); + expect(processBoxShadow('red asf 5px 2px 3px')).toEqual([]); }); it('should fail to parse negative blur', () => { - expect(processBoxShadow('red 5 2 -3')).toEqual([]); + expect(processBoxShadow('red 5px 2px -3px')).toEqual([]); + }); + + it('should fail to parse missing unit', () => { + expect(processBoxShadow('10px 5')).toEqual([]); }); it('should parse simple object', () => { diff --git a/packages/react-native/Libraries/StyleSheet/processBoxShadow.js b/packages/react-native/Libraries/StyleSheet/processBoxShadow.js index c801063ebb7..faa4b517acb 100644 --- a/packages/react-native/Libraries/StyleSheet/processBoxShadow.js +++ b/packages/react-native/Libraries/StyleSheet/processBoxShadow.js @@ -205,5 +205,9 @@ function parseLength(length: string): ?number { return null; } + if (match[3] == null && match[1] !== '0') { + return null; + } + return Number(match[1]); }