Skip to content

Commit 63ed190

Browse files
miladfarcacopybara-github
authored andcommitted
Add a patch file to fix zoneinfo64 parsing on big endian platforms
On big endian platforms ICU4C provides data in native BE order causing ZoneInfo64 parsing to fail with "Failed to load timezone info" and is causing test failures on Node.js after enabling temporal on BE: nodejs/node#61808 This CL uses `from_ne_bytes` to read data in native endian order instead. Patch is also applied to ICU4X upstream: unicode-org/icu4x#7658 Bug: 401065166 Change-Id: Ib6d38b0decc2365187663b4eac5e2dfd3a975aa4 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7583895 Reviewed-by: Manish Goregaokar <manishearth@google.com> Commit-Queue: Manish Goregaokar <manishearth@google.com> Reviewed-by: Łukasz Anforowicz <lukasza@chromium.org> Cr-Commit-Position: refs/heads/main@{#1588862} NOKEYCHECK=True GitOrigin-RevId: 19ec3dce45600fc7c825f921ac1cebe3bc63e1ba
1 parent 6db2c3e commit 63ed190

4 files changed

Lines changed: 101 additions & 9 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
From d0039d5c3f186da26ba1e8b9fabe5362d22d6035 Mon Sep 17 00:00:00 2001
2+
From: Milad Fa <mfarazma@ibm.com>
3+
Date: Tue, 17 Feb 2026 21:27:42 +0000
4+
Subject: [PATCH] [temporal] Fix zoneinfo64 parsing on big endian platforms
5+
6+
---
7+
.../chromium_crates_io/vendor/resb-v0_1/src/binary.rs | 2 +-
8+
.../vendor/resb-v0_1/src/binary/deserializer.rs | 11 ++++++++---
9+
.../vendor/resb-v0_1/src/binary/header.rs | 7 ++-----
10+
3 files changed, 11 insertions(+), 9 deletions(-)
11+
12+
diff --git a/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary.rs b/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary.rs
13+
index 5269bbd28c980..fd9081fbe065f 100644
14+
--- a/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary.rs
15+
+++ b/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary.rs
16+
@@ -473,7 +473,7 @@ fn read_u16(input: &[u8]) -> Result<(u16, &[u8]), BinaryDeserializerError> {
17+
let bytes = get_subslice(input, ..core::mem::size_of::<u16>())?
18+
.try_into()
19+
.unwrap();
20+
- let value = u16::from_le_bytes(bytes);
21+
+ let value = u16::from_ne_bytes(bytes);
22+
23+
let rest = get_subslice(input, core::mem::size_of::<u16>()..)?;
24+
Ok((value, rest))
25+
diff --git a/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary/deserializer.rs b/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary/deserializer.rs
26+
index d52f568146013..c533e67d509c4 100644
27+
--- a/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary/deserializer.rs
28+
+++ b/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary/deserializer.rs
29+
@@ -23,6 +23,11 @@ const SYSTEM_CHARSET_FAMILY: CharsetFamily = CharsetFamily::Ascii;
30+
31+
/// Deserializes an instance of type `T` from bytes representing a binary ICU
32+
/// resource bundle.
33+
+///
34+
+/// The input data must be in the platform's native endianness. ICU4C resource
35+
+/// bundles such as `zoneinfo64.res` are generated in both little endian and
36+
+/// big endian formats; callers must ensure the appropriate format is provided
37+
+/// for the target platform.
38+
pub fn from_words<'a, T>(input: &'a [u32]) -> Result<T, BinaryDeserializerError>
39+
where
40+
T: Deserialize<'a>,
41+
@@ -142,7 +147,7 @@ impl<'de> ResourceTreeDeserializer<'de> {
42+
))
43+
}
44+
};
45+
- let descriptor = u32::from_le_bytes(descriptor);
46+
+ let descriptor = u32::from_ne_bytes(descriptor);
47+
48+
ResDescriptor::try_from(descriptor)
49+
}
50+
@@ -887,7 +892,7 @@ impl<'de> Resource16BitDeserializer<'de> {
51+
// exactly 2 bytes.
52+
#[expect(clippy::unwrap_used)]
53+
let bytes = <[u8; 2]>::try_from(bytes).unwrap();
54+
- u16::from_le_bytes(bytes)
55+
+ u16::from_ne_bytes(bytes)
56+
});
57+
58+
char::decode_utf16(units)
59+
@@ -1255,7 +1260,7 @@ fn read_u32(input: &[u8]) -> Result<(u32, &[u8]), BinaryDeserializerError> {
60+
))?
61+
.try_into()
62+
.unwrap();
63+
- let value = u32::from_le_bytes(bytes);
64+
+ let value = u32::from_ne_bytes(bytes);
65+
66+
let rest =
67+
input
68+
diff --git a/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary/header.rs b/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary/header.rs
69+
index be776f404ea86..41535a4cf6f48 100644
70+
--- a/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary/header.rs
71+
+++ b/third_party/rust/chromium_crates_io/vendor/resb-v0_1/src/binary/header.rs
72+
@@ -113,13 +113,10 @@ impl TryFrom<&[u8]> for BinReprInfo {
73+
let (size, value) = read_u16(value)?;
74+
let (reserved_word, value) = read_u16(value)?;
75+
76+
- // While the consumer is responsible for verifying acceptability of most
77+
- // contents of the repr info, we explicitly depend on little endian data
78+
- // in order to ensure compatibility with `zerovec`.
79+
let (endianness, value) = (Endianness::try_from(value[0])?, &value[1..]);
80+
- if endianness != Endianness::Little {
81+
+ if (endianness == Endianness::Little) != cfg!(target_endian = "little") {
82+
return Err(BinaryDeserializerError::unsupported_format(
83+
- "big-endian bundles are not supported",
84+
+ "bundle endianness does not match platform endianness",
85+
));
86+
}
87+
88+
--
89+
2.47.0
90+

chromium_crates_io/vendor/resb-v0_1/src/binary.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ fn read_u16(input: &[u8]) -> Result<(u16, &[u8]), BinaryDeserializerError> {
473473
let bytes = get_subslice(input, ..core::mem::size_of::<u16>())?
474474
.try_into()
475475
.unwrap();
476-
let value = u16::from_le_bytes(bytes);
476+
let value = u16::from_ne_bytes(bytes);
477477

478478
let rest = get_subslice(input, core::mem::size_of::<u16>()..)?;
479479
Ok((value, rest))

chromium_crates_io/vendor/resb-v0_1/src/binary/deserializer.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ const SYSTEM_CHARSET_FAMILY: CharsetFamily = CharsetFamily::Ascii;
2323

2424
/// Deserializes an instance of type `T` from bytes representing a binary ICU
2525
/// resource bundle.
26+
///
27+
/// The input data must be in the platform's native endianness. ICU4C resource
28+
/// bundles such as `zoneinfo64.res` are generated in both little endian and
29+
/// big endian formats; callers must ensure the appropriate format is provided
30+
/// for the target platform.
2631
pub fn from_words<'a, T>(input: &'a [u32]) -> Result<T, BinaryDeserializerError>
2732
where
2833
T: Deserialize<'a>,
@@ -142,7 +147,7 @@ impl<'de> ResourceTreeDeserializer<'de> {
142147
))
143148
}
144149
};
145-
let descriptor = u32::from_le_bytes(descriptor);
150+
let descriptor = u32::from_ne_bytes(descriptor);
146151

147152
ResDescriptor::try_from(descriptor)
148153
}
@@ -887,7 +892,7 @@ impl<'de> Resource16BitDeserializer<'de> {
887892
// exactly 2 bytes.
888893
#[expect(clippy::unwrap_used)]
889894
let bytes = <[u8; 2]>::try_from(bytes).unwrap();
890-
u16::from_le_bytes(bytes)
895+
u16::from_ne_bytes(bytes)
891896
});
892897

893898
char::decode_utf16(units)
@@ -1255,7 +1260,7 @@ fn read_u32(input: &[u8]) -> Result<(u32, &[u8]), BinaryDeserializerError> {
12551260
))?
12561261
.try_into()
12571262
.unwrap();
1258-
let value = u32::from_le_bytes(bytes);
1263+
let value = u32::from_ne_bytes(bytes);
12591264

12601265
let rest =
12611266
input

chromium_crates_io/vendor/resb-v0_1/src/binary/header.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,10 @@ impl TryFrom<&[u8]> for BinReprInfo {
113113
let (size, value) = read_u16(value)?;
114114
let (reserved_word, value) = read_u16(value)?;
115115

116-
// While the consumer is responsible for verifying acceptability of most
117-
// contents of the repr info, we explicitly depend on little endian data
118-
// in order to ensure compatibility with `zerovec`.
119116
let (endianness, value) = (Endianness::try_from(value[0])?, &value[1..]);
120-
if endianness != Endianness::Little {
117+
if (endianness == Endianness::Little) != cfg!(target_endian = "little") {
121118
return Err(BinaryDeserializerError::unsupported_format(
122-
"big-endian bundles are not supported",
119+
"bundle endianness does not match platform endianness",
123120
));
124121
}
125122

0 commit comments

Comments
 (0)