From bc63dfe662d6b18ad8fed6bdcc9d91eeb2d8e76d Mon Sep 17 00:00:00 2001 From: Kostia Sokolovskyi Date: Wed, 14 Jan 2026 15:55:29 +0100 Subject: [PATCH] [web] Fix loading of fragment shader with space in name. (#180919) Fixes https://github.com/flutter/flutter/issues/180862 ### Description - Adds `assetKey` encoding in `FragmentProgram.fromAsset` in `web_ui` to be consistent with the implementation in `ui` https://github.com/flutter/flutter/blob/7e176f8c3fde96342b2c61e5b4043d53113a2b31/engine/src/flutter/lib/ui/painting.dart#L5354-L5369 - Adds test ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [X] I signed the [CLA]. - [X] I listed at least one issue that this PR fixes in the description above. - [X] I updated/added relevant documentation (doc comments with `///`). - [X] I added new tests to check the change I am making, or this PR is [test-exempt]. - [X] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [X] All existing and new tests are passing. [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --- engine/src/flutter/lib/web_ui/lib/painting.dart | 7 ++++++- .../flutter/lib/web_ui/test/ui/fragment_shader_test.dart | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/lib/web_ui/lib/painting.dart b/engine/src/flutter/lib/web_ui/lib/painting.dart index 75218bab0b1..88ff3ae391e 100644 --- a/engine/src/flutter/lib/web_ui/lib/painting.dart +++ b/engine/src/flutter/lib/web_ui/lib/painting.dart @@ -1004,7 +1004,12 @@ class ImageDescriptor { abstract class FragmentProgram { static Future fromAsset(String assetKey) { - return engine.renderer.createFragmentProgram(assetKey); + // The flutter tool converts all asset keys with spaces into URI + // encoded paths (replacing ' ' with '%20', for example). We perform + // the same encoding here so that users can load assets with the same + // key they have written in the pubspec. + final String encodedKey = Uri(path: Uri.encodeFull(assetKey)).path; + return engine.renderer.createFragmentProgram(encodedKey); } FragmentShader fragmentShader(); diff --git a/engine/src/flutter/lib/web_ui/test/ui/fragment_shader_test.dart b/engine/src/flutter/lib/web_ui/test/ui/fragment_shader_test.dart index ea0ee333fef..ce3d1f8e9e7 100644 --- a/engine/src/flutter/lib/web_ui/test/ui/fragment_shader_test.dart +++ b/engine/src/flutter/lib/web_ui/test/ui/fragment_shader_test.dart @@ -417,6 +417,12 @@ Future testMain() async { }, skip: isWimp); // https://github.com/flutter/flutter/issues/175431 } + // Regression test for https://github.com/flutter/flutter/issues/180862. + test('fragment shader with space in name loads correctly', () async { + assetScope.setAsset('voronoi%20shader', ByteData.sublistView(utf8.encode(kVoronoiShaderSksl))); + await expectLater(ui.FragmentProgram.fromAsset('voronoi shader'), completes); + }, skip: isWimp); // https://github.com/flutter/flutter/issues/175431 + test('getUniformFloat works with correct datatype', () async { final ui.FragmentProgram program = await renderer.createFragmentProgram('ink_sparkle'); final ui.FragmentShader shader = program.fragmentShader();