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::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
|
use std::io::Read;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -58,11 +62,7 @@ pub struct StandaloneData {
|
||||||
pub fn extract_standalone(
|
pub fn extract_standalone(
|
||||||
cli_args: Cow<Vec<OsString>>,
|
cli_args: Cow<Vec<OsString>>,
|
||||||
) -> Result<StandaloneData, AnyError> {
|
) -> Result<StandaloneData, AnyError> {
|
||||||
let Some(data) = libsui::find_section("d3n0l4nd")
|
let data = find_section()?;
|
||||||
.context("Failed reading standalone binary section.")?
|
|
||||||
else {
|
|
||||||
bail!("Could not find standalone binary section.")
|
|
||||||
};
|
|
||||||
|
|
||||||
let root_path = {
|
let root_path = {
|
||||||
let maybe_current_exe = std::env::current_exe().ok();
|
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 struct DeserializedDataSection {
|
||||||
pub metadata: Metadata,
|
pub metadata: Metadata,
|
||||||
pub npm_snapshot: Option<ValidSerializedNpmResolutionSnapshot>,
|
pub npm_snapshot: Option<ValidSerializedNpmResolutionSnapshot>,
|
||||||
|
|
|
@ -267,6 +267,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
||||||
// Phase 2 of the 'min sized' deno compile RFC talks
|
// Phase 2 of the 'min sized' deno compile RFC talks
|
||||||
// about adding this as a flag.
|
// about adding this as a flag.
|
||||||
if let Some(path) = get_dev_binary_path() {
|
if let Some(path) = get_dev_binary_path() {
|
||||||
|
log::debug!("Resolved denort: {}", path.to_string_lossy());
|
||||||
return std::fs::read(&path).with_context(|| {
|
return std::fs::read(&path).with_context(|| {
|
||||||
format!("Could not find denort at '{}'", path.to_string_lossy())
|
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 download_directory = self.deno_dir.dl_folder_path();
|
||||||
let binary_path = download_directory.join(&binary_path_suffix);
|
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> {
|
let read_file = |path: &Path| -> Result<Vec<u8>, AnyError> {
|
||||||
std::fs::read(path).with_context(|| format!("Reading {}", path.display()))
|
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