mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
fix(compile): temporarily fallback to reading resource data from file on windows (#29024)
Temp hacky fix for https://github.com/denoland/deno/issues/28982
This commit is contained in:
parent
74425ddb0b
commit
3d16eb8ff3
4 changed files with 136 additions and 5 deletions
122
cli/rt/binary.rs
122
cli/rt/binary.rs
|
@ -3,7 +3,11 @@
|
|||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::fs::File;
|
||||
use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
use std::io::ErrorKind;
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
@ -58,11 +62,7 @@ pub struct StandaloneData {
|
|||
pub fn extract_standalone(
|
||||
cli_args: Cow<Vec<OsString>>,
|
||||
) -> Result<StandaloneData, AnyError> {
|
||||
let Some(data) = libsui::find_section("d3n0l4nd")
|
||||
.context("Failed reading standalone binary section.")?
|
||||
else {
|
||||
bail!("Could not find standalone binary section.")
|
||||
};
|
||||
let data = find_section()?;
|
||||
|
||||
let root_path = {
|
||||
let maybe_current_exe = std::env::current_exe().ok();
|
||||
|
@ -117,6 +117,118 @@ pub fn extract_standalone(
|
|||
})
|
||||
}
|
||||
|
||||
fn find_section() -> Result<&'static [u8], AnyError> {
|
||||
if std::env::var_os("DENO_INTERNAL_RT_USE_FILE_FALLBACK").is_some() {
|
||||
return read_from_file_fallback();
|
||||
}
|
||||
match libsui::find_section("d3n0l4nd")
|
||||
.context("Failed reading standalone binary section.")
|
||||
{
|
||||
Ok(Some(data)) => Ok(data),
|
||||
Ok(None) => bail!("Could not find standalone binary section."),
|
||||
Err(err) => {
|
||||
if cfg!(windows) {
|
||||
if let Ok(data) = read_from_file_fallback() {
|
||||
return Ok(data);
|
||||
}
|
||||
}
|
||||
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This is a temporary hacky fallback until we can find
|
||||
/// a fix for https://github.com/denoland/deno/issues/28982
|
||||
fn read_from_file_fallback() -> Result<&'static [u8], AnyError> {
|
||||
// search for DENOLAND in utf16
|
||||
const MARKER: &[u8] = &[
|
||||
0x44, 0x00, 0x33, 0x00, 0x4E, 0x00, 0x30, 0x00, 0x4C, 0x00, 0x34, 0x00,
|
||||
0x4E, 0x00, 0x44, 0x00,
|
||||
];
|
||||
const ASCII_SENTINEL: &[u8] = b"d3n0l4nd";
|
||||
let file_path = std::env::current_exe()?;
|
||||
const BUF_CAP: usize = 64 * 1024;
|
||||
|
||||
let file = File::open(file_path)?;
|
||||
let mut r = BufReader::with_capacity(BUF_CAP, file);
|
||||
|
||||
fn scan<R: Read>(
|
||||
reader: &mut BufReader<R>,
|
||||
needle: &[u8],
|
||||
) -> std::io::Result<Option<Vec<u8>>> {
|
||||
let mut overlap = Vec::<u8>::with_capacity(needle.len().saturating_sub(1));
|
||||
let mut out = None;
|
||||
|
||||
loop {
|
||||
let chunk = reader.fill_buf()?;
|
||||
if chunk.is_empty() {
|
||||
return Ok(out);
|
||||
}
|
||||
|
||||
// search in overlap+chunk
|
||||
let mut search_space = overlap.clone();
|
||||
search_space.extend_from_slice(chunk);
|
||||
|
||||
if let Some(pos) =
|
||||
search_space.windows(needle.len()).position(|w| w == needle)
|
||||
{
|
||||
// How far into `chunk` does the match **end**?
|
||||
let bytes_before_chunk = overlap.len();
|
||||
let match_end_in_chunk = pos + needle.len() - bytes_before_chunk;
|
||||
|
||||
// Consume up to the end of the needle
|
||||
reader.consume(match_end_in_chunk);
|
||||
|
||||
// Everything *after* the match that is already in memory
|
||||
let tail_in_mem = &search_space[pos..]; // begins with the needle
|
||||
out = Some(tail_in_mem.to_vec());
|
||||
break;
|
||||
}
|
||||
|
||||
// Prepare next overlap (needle.len()-1 bytes)
|
||||
overlap.clear();
|
||||
let keep = needle.len().saturating_sub(1);
|
||||
if search_space.len() >= keep {
|
||||
overlap.extend_from_slice(&search_space[search_space.len() - keep..]);
|
||||
} else {
|
||||
overlap.extend_from_slice(&search_space);
|
||||
}
|
||||
|
||||
let chunk_len = chunk.len(); // prevent multiple borrow
|
||||
reader.consume(chunk_len);
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
// skip up to and including MARKER
|
||||
if scan(&mut r, MARKER)?.is_none() {
|
||||
bail!("Failed to find.");
|
||||
}
|
||||
|
||||
// collect from ASCII_SENTINEL onward
|
||||
let mut result = scan(&mut r, ASCII_SENTINEL)?.ok_or_else(|| {
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::UnexpectedEof,
|
||||
"ASCII sentinel not found",
|
||||
)
|
||||
})?;
|
||||
|
||||
r.read_to_end(&mut result)?;
|
||||
|
||||
if let Some(last_pos) = result
|
||||
.windows(ASCII_SENTINEL.len())
|
||||
.rposition(|w| w == ASCII_SENTINEL)
|
||||
{
|
||||
result.truncate(last_pos + ASCII_SENTINEL.len());
|
||||
} else {
|
||||
bail!("Failed to find.");
|
||||
}
|
||||
|
||||
Ok(Box::leak(result.into_boxed_slice()))
|
||||
}
|
||||
|
||||
pub struct DeserializedDataSection {
|
||||
pub metadata: Metadata,
|
||||
pub npm_snapshot: Option<ValidSerializedNpmResolutionSnapshot>,
|
||||
|
|
|
@ -267,6 +267,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
// Phase 2 of the 'min sized' deno compile RFC talks
|
||||
// about adding this as a flag.
|
||||
if let Some(path) = get_dev_binary_path() {
|
||||
log::debug!("Resolved denort: {}", path.to_string_lossy());
|
||||
return std::fs::read(&path).with_context(|| {
|
||||
format!("Could not find denort at '{}'", path.to_string_lossy())
|
||||
});
|
||||
|
@ -286,6 +287,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
|
||||
let download_directory = self.deno_dir.dl_folder_path();
|
||||
let binary_path = download_directory.join(&binary_path_suffix);
|
||||
log::debug!("Resolved denort: {}", binary_path.display());
|
||||
|
||||
let read_file = |path: &Path| -> Result<Vec<u8>, AnyError> {
|
||||
std::fs::read(path).with_context(|| format!("Reading {}", path.display()))
|
||||
|
|
16
tests/specs/compile/fallback/__test__.jsonc
Normal file
16
tests/specs/compile/fallback/__test__.jsonc
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"envs": {
|
||||
"DENO_INTERNAL_RT_USE_FILE_FALLBACK": "1"
|
||||
},
|
||||
"tempDir": true,
|
||||
"steps": [{
|
||||
"if": "windows",
|
||||
"args": "compile --output bin main.ts",
|
||||
"output": "[WILDCARD]"
|
||||
}, {
|
||||
"if": "windows",
|
||||
"commandName": "./bin",
|
||||
"args": [],
|
||||
"output": "HI\n"
|
||||
}]
|
||||
}
|
1
tests/specs/compile/fallback/main.ts
Normal file
1
tests/specs/compile/fallback/main.ts
Normal file
|
@ -0,0 +1 @@
|
|||
console.log("HI");
|
Loading…
Add table
Add a link
Reference in a new issue