Skip to content

Commit cc27962

Browse files
chrfalchreact-native-bot
authored andcommitted
fix(cocoapods): escape local file URIs for unicode paths (#56907)
Summary: #56878 shows that using unicode characters in paths fails with pod install. Expo fixed this internally here: expo/expo#45779 Fixes #56878 ## How: Build local `file://` sources through a shared helper that percent-encodes filesystem paths before passing them to `URI::File.build`. This avoids Ruby/CocoaPods URI failures when React Native projects or local prebuilt tarballs live under paths containing Unicode characters or spaces. Apply the helper to `RNCore` and `ReactNativeDependencies` local tarball sources, including RNCore dSYM-processed prebuilt paths, while leaving remote Maven and Sonatype URLs unchanged. Add focused coverage for Unicode, spaces, ASCII paths, and the raw `URI::File.build` regression case. ## Changelog: [IOS] [FIXED] - fixed escaping local file URIs for unicode paths in ruby scripts Pull Request resolved: #56907 Test Plan: - Test with creating a new project in a path containing a unicode character and the run pod install. Reviewed By: cortinico Differential Revision: D105968728 Pulled By: cipolleschi fbshipit-source-id: 6d5b9043aafe3d86494f3b5ca0f208e46f1f3739
1 parent 6c6511c commit cc27962

4 files changed

Lines changed: 57 additions & 4 deletions

File tree

packages/react-native/scripts/cocoapods/__tests__/utils-test.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,53 @@ def teardown
3939
$RN_PLATFORMS = nil
4040
end
4141

42+
# ===================== #
43+
# TEST - localFileUri #
44+
# ===================== #
45+
46+
def test_localFileUri_whenPathContainsUnicode_returnsEscapedFileUri
47+
# Arrange
48+
path = "/tmp/rn-unicode/💻dev/React-Core-prebuilt.tar.gz"
49+
50+
# Act
51+
result = ReactNativePodsUtils.local_file_uri(path)
52+
53+
# Assert
54+
assert_equal("file:///tmp/rn-unicode/%F0%9F%92%BBdev/React-Core-prebuilt.tar.gz", result)
55+
end
56+
57+
def test_localFileUri_whenPathContainsSpaces_returnsEscapedFileUri
58+
# Arrange
59+
path = "/tmp/rn space/React Core.tar.gz"
60+
61+
# Act
62+
result = ReactNativePodsUtils.local_file_uri(path)
63+
64+
# Assert
65+
assert_equal("file:///tmp/rn%20space/React%20Core.tar.gz", result)
66+
end
67+
68+
def test_localFileUri_whenPathContainsOnlyAscii_returnsFileUri
69+
# Arrange
70+
path = "/tmp/rn-ascii/React-Core-prebuilt.tar.gz"
71+
72+
# Act
73+
result = ReactNativePodsUtils.local_file_uri(path)
74+
75+
# Assert
76+
assert_equal("file:///tmp/rn-ascii/React-Core-prebuilt.tar.gz", result)
77+
end
78+
79+
def test_localFileUri_whenPathContainsUnicode_withoutEscapingUriFileBuildRaises
80+
# Arrange
81+
path = "/tmp/rn-unicode/💻dev/React-Core-prebuilt.tar.gz"
82+
83+
# Act & Assert
84+
assert_raise(URI::InvalidComponentError) do
85+
URI::File.build(path: path).to_s
86+
end
87+
end
88+
4289
# ======================= #
4390
# TEST - warnIfNotOnArm64 #
4491
# ======================= #

packages/react-native/scripts/cocoapods/rncore.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def self.resolve_podspec_source()
103103
if ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"]
104104
abort_if_use_local_rncore_with_no_file()
105105
rncore_log("Using local xcframework at #{ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"]}")
106-
return {:http => "file://#{ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"]}" }
106+
return {:http => ReactNativePodsUtils.local_file_uri(ENV["RCT_TESTONLY_RNCORE_TARBALL_PATH"]) }
107107
end
108108

109109
if ENV["RCT_USE_PREBUILT_RNCORE"] == "1"
@@ -161,7 +161,7 @@ def self.podspec_source_download_prebuild_stable_tarball()
161161
rncore_log(" #{Pathname.new(destinationRelease).relative_path_from(Pathname.pwd).to_s}")
162162

163163
return {:http => stable_tarball_url(@@react_native_version, :debug) } unless @@download_dsyms
164-
return {:http => URI::File.build(path: destinationDebug).to_s }
164+
return {:http => ReactNativePodsUtils.local_file_uri(destinationDebug) }
165165
end
166166

167167
def self.podspec_source_download_prebuilt_nightly_tarball()
@@ -198,7 +198,7 @@ def self.podspec_source_download_prebuilt_nightly_tarball()
198198
rncore_log(" #{Pathname.new(destinationDebug).relative_path_from(Pathname.pwd).to_s}")
199199
rncore_log(" #{Pathname.new(destinationRelease).relative_path_from(Pathname.pwd).to_s}")
200200
return {:http => nightly_tarball_url(@@react_native_version, :debug) } unless @@download_dsyms
201-
return {:http => URI::File.build(path: destinationDebug).to_s }
201+
return {:http => ReactNativePodsUtils.local_file_uri(destinationDebug) }
202202
end
203203

204204
def self.process_dsyms(frameworkTarball, dSymsTarball)

packages/react-native/scripts/cocoapods/rndependencies.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def self.resolve_podspec_source()
7070
if ENV["RCT_USE_LOCAL_RN_DEP"]
7171
abort_if_use_local_rndeps_with_no_file()
7272
rndeps_log("Using local xcframework at #{ENV["RCT_USE_LOCAL_RN_DEP"]}")
73-
return {:http => "file://#{ENV["RCT_USE_LOCAL_RN_DEP"]}" }
73+
return {:http => ReactNativePodsUtils.local_file_uri(ENV["RCT_USE_LOCAL_RN_DEP"]) }
7474
end
7575

7676
if ENV["RCT_USE_RN_DEP"] && ENV["RCT_USE_RN_DEP"] == "1"

packages/react-native/scripts/cocoapods/utils.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@
55

66
require 'shellwords'
77
require 'digest'
8+
require 'uri'
89

910
require_relative "./helpers.rb"
1011
require_relative "./jsengine.rb"
1112

1213
# Utilities class for React Native Cocoapods
1314
class ReactNativePodsUtils
15+
# URI::File.build validates path components as ASCII, so escape the filesystem path first.
16+
def self.local_file_uri(path)
17+
URI::File.build(path: URI::DEFAULT_PARSER.escape(path)).to_s
18+
end
19+
1420
def self.warn_if_not_on_arm64
1521
if SysctlChecker.new().call_sysctl_arm64() == 1 && !Environment.new().ruby_platform().include?('arm64')
1622
Pod::UI.warn 'Do not use "pod install" from inside Rosetta2 (x86_64 emulation on arm64).'

0 commit comments

Comments
 (0)