aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-php-shim/src/string.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-23 12:43:10 +0900
committernsfisis <nsfisis@gmail.com>2026-08-23 13:24:29 +0900
commit0b48f4a46d24248e4c012ef37d25b5963c27a78c (patch)
treea4c189be4419ded8e2252bc0c250aecfc66b3c36 /crates/shirabe-php-shim/src/string.rs
parent890a50de2a740cc4c4edba12b37cc9aa4d0efdc5 (diff)
downloadphp-shirabe-0b48f4a46d24248e4c012ef37d25b5963c27a78c.tar.gz
php-shirabe-0b48f4a46d24248e4c012ef37d25b5963c27a78c.tar.zst
php-shirabe-0b48f4a46d24248e4c012ef37d25b5963c27a78c.zip
fix(fs): carry file_get_contents results as bytes
file_get_contents() and file_get_contents_with_max_length() return Vec<u8> instead of a from_utf8_lossy'd String. Call sites whose consumer takes a &str still convert lossily and are marked TODO(bytes). file_get_contents_with_max_length() now reads at most the requested number of bytes instead of the whole file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-php-shim/src/string.rs')
-rw-r--r--crates/shirabe-php-shim/src/string.rs15
1 files changed, 9 insertions, 6 deletions
diff --git a/crates/shirabe-php-shim/src/string.rs b/crates/shirabe-php-shim/src/string.rs
index 024a3943..3a61a59d 100644
--- a/crates/shirabe-php-shim/src/string.rs
+++ b/crates/shirabe-php-shim/src/string.rs
@@ -299,11 +299,8 @@ pub fn trim(s: &str, chars: Option<&str>) -> String {
}
// Byte-based, matching PHP's substr. A negative start/length counts from the end.
-// The result is reinterpreted as UTF-8 (lossily), which only matters when a slice
-// boundary falls inside a multibyte sequence.
-pub fn substr(s: &str, start: i64, length: Option<i64>) -> String {
- let bytes = s.as_bytes();
- let len = bytes.len() as i64;
+pub fn substr_bytes(s: &[u8], start: i64, length: Option<i64>) -> Vec<u8> {
+ let len = s.len() as i64;
let start = if start < 0 {
(len + start).max(0)
} else {
@@ -314,7 +311,13 @@ pub fn substr(s: &str, start: i64, length: Option<i64>) -> String {
Some(l) if l < 0 => (len + l).max(start),
Some(l) => (start + l).min(len),
};
- String::from_utf8_lossy(&bytes[start as usize..end as usize]).into_owned()
+ s[start as usize..end as usize].to_vec()
+}
+
+// The result is reinterpreted as UTF-8 (lossily), which only matters when a slice
+// boundary falls inside a multibyte sequence.
+pub fn substr(s: &str, start: i64, length: Option<i64>) -> String {
+ String::from_utf8_lossy(&substr_bytes(s.as_bytes(), start, length)).into_owned()
}
pub fn implode(glue: &str, pieces: &[String]) -> String {