mirror of
https://github.com/denoland/deno.git
synced 2024-12-18 13:22:55 -05:00
fix(compile): correct read length for transpiled typescript files (#27301)
Extracted out of https://github.com/denoland/deno/pull/27296/files It's hard to test for this, but a test for this is in that other PR.
This commit is contained in:
parent
d99b2d6f7d
commit
94c7653d0e
1 changed files with 48 additions and 27 deletions
|
@ -266,17 +266,20 @@ impl VfsBuilder {
|
||||||
|
|
||||||
let dir = self.add_dir(path.parent().unwrap())?;
|
let dir = self.add_dir(path.parent().unwrap())?;
|
||||||
let name = path.file_name().unwrap().to_string_lossy();
|
let name = path.file_name().unwrap().to_string_lossy();
|
||||||
let data_len = data.len();
|
let offset_and_len = OffsetWithLength {
|
||||||
|
offset,
|
||||||
|
len: data.len() as u64,
|
||||||
|
};
|
||||||
match dir.entries.binary_search_by(|e| e.name().cmp(&name)) {
|
match dir.entries.binary_search_by(|e| e.name().cmp(&name)) {
|
||||||
Ok(index) => {
|
Ok(index) => {
|
||||||
let entry = &mut dir.entries[index];
|
let entry = &mut dir.entries[index];
|
||||||
match entry {
|
match entry {
|
||||||
VfsEntry::File(virtual_file) => match sub_data_kind {
|
VfsEntry::File(virtual_file) => match sub_data_kind {
|
||||||
VfsFileSubDataKind::Raw => {
|
VfsFileSubDataKind::Raw => {
|
||||||
virtual_file.offset = offset;
|
virtual_file.offset = offset_and_len;
|
||||||
}
|
}
|
||||||
VfsFileSubDataKind::ModuleGraph => {
|
VfsFileSubDataKind::ModuleGraph => {
|
||||||
virtual_file.module_graph_offset = offset;
|
virtual_file.module_graph_offset = offset_and_len;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
VfsEntry::Dir(_) | VfsEntry::Symlink(_) => unreachable!(),
|
VfsEntry::Dir(_) | VfsEntry::Symlink(_) => unreachable!(),
|
||||||
|
@ -287,9 +290,8 @@ impl VfsBuilder {
|
||||||
insert_index,
|
insert_index,
|
||||||
VfsEntry::File(VirtualFile {
|
VfsEntry::File(VirtualFile {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
offset,
|
offset: offset_and_len,
|
||||||
module_graph_offset: offset,
|
module_graph_offset: offset_and_len,
|
||||||
len: data.len() as u64,
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -298,7 +300,7 @@ impl VfsBuilder {
|
||||||
// new file, update the list of files
|
// new file, update the list of files
|
||||||
if self.current_offset == offset {
|
if self.current_offset == offset {
|
||||||
self.files.push(data);
|
self.files.push(data);
|
||||||
self.current_offset += data_len as u64;
|
self.current_offset += offset_and_len.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -403,7 +405,7 @@ impl<'a> VfsEntryRef<'a> {
|
||||||
mtime: None,
|
mtime: None,
|
||||||
ctime: None,
|
ctime: None,
|
||||||
blksize: 0,
|
blksize: 0,
|
||||||
size: file.len,
|
size: file.offset.len,
|
||||||
dev: 0,
|
dev: 0,
|
||||||
ino: 0,
|
ino: 0,
|
||||||
mode: 0,
|
mode: 0,
|
||||||
|
@ -472,27 +474,41 @@ impl VfsEntry {
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct VirtualDirectory {
|
pub struct VirtualDirectory {
|
||||||
|
#[serde(rename = "n")]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
// should be sorted by name
|
// should be sorted by name
|
||||||
|
#[serde(rename = "e")]
|
||||||
pub entries: Vec<VfsEntry>,
|
pub entries: Vec<VfsEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
pub struct OffsetWithLength {
|
||||||
|
#[serde(rename = "o")]
|
||||||
|
pub offset: u64,
|
||||||
|
#[serde(rename = "l")]
|
||||||
|
pub len: u64,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct VirtualFile {
|
pub struct VirtualFile {
|
||||||
|
#[serde(rename = "n")]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub offset: u64,
|
#[serde(rename = "o")]
|
||||||
|
pub offset: OffsetWithLength,
|
||||||
/// Offset file to use for module loading when it differs from the
|
/// Offset file to use for module loading when it differs from the
|
||||||
/// raw file. Often this will be the same offset as above for data
|
/// raw file. Often this will be the same offset as above for data
|
||||||
/// such as JavaScript files, but for TypeScript files the `offset`
|
/// such as JavaScript files, but for TypeScript files the `offset`
|
||||||
/// will be the original raw bytes when included as an asset and this
|
/// will be the original raw bytes when included as an asset and this
|
||||||
/// offset will be to the transpiled JavaScript source.
|
/// offset will be to the transpiled JavaScript source.
|
||||||
pub module_graph_offset: u64,
|
#[serde(rename = "m")]
|
||||||
pub len: u64,
|
pub module_graph_offset: OffsetWithLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct VirtualSymlink {
|
pub struct VirtualSymlink {
|
||||||
|
#[serde(rename = "n")]
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
#[serde(rename = "p")]
|
||||||
pub dest_parts: Vec<String>,
|
pub dest_parts: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +652,7 @@ impl FileBackedVfsFile {
|
||||||
Ok(pos)
|
Ok(pos)
|
||||||
}
|
}
|
||||||
SeekFrom::End(offset) => {
|
SeekFrom::End(offset) => {
|
||||||
if offset < 0 && -offset as u64 > self.file.len {
|
if offset < 0 && -offset as u64 > self.file.offset.len {
|
||||||
let msg = "An attempt was made to move the file pointer before the beginning of the file.";
|
let msg = "An attempt was made to move the file pointer before the beginning of the file.";
|
||||||
Err(
|
Err(
|
||||||
std::io::Error::new(std::io::ErrorKind::PermissionDenied, msg)
|
std::io::Error::new(std::io::ErrorKind::PermissionDenied, msg)
|
||||||
|
@ -645,9 +661,9 @@ impl FileBackedVfsFile {
|
||||||
} else {
|
} else {
|
||||||
let mut current_pos = self.pos.lock();
|
let mut current_pos = self.pos.lock();
|
||||||
*current_pos = if offset >= 0 {
|
*current_pos = if offset >= 0 {
|
||||||
self.file.len - (offset as u64)
|
self.file.offset.len - (offset as u64)
|
||||||
} else {
|
} else {
|
||||||
self.file.len + (-offset as u64)
|
self.file.offset.len + (-offset as u64)
|
||||||
};
|
};
|
||||||
Ok(*current_pos)
|
Ok(*current_pos)
|
||||||
}
|
}
|
||||||
|
@ -671,7 +687,7 @@ impl FileBackedVfsFile {
|
||||||
let mut pos = self.pos.lock();
|
let mut pos = self.pos.lock();
|
||||||
let read_pos = *pos;
|
let read_pos = *pos;
|
||||||
// advance the position due to the read
|
// advance the position due to the read
|
||||||
*pos = std::cmp::min(self.file.len, *pos + buf.len() as u64);
|
*pos = std::cmp::min(self.file.offset.len, *pos + buf.len() as u64);
|
||||||
read_pos
|
read_pos
|
||||||
};
|
};
|
||||||
self
|
self
|
||||||
|
@ -685,13 +701,13 @@ impl FileBackedVfsFile {
|
||||||
let mut pos = self.pos.lock();
|
let mut pos = self.pos.lock();
|
||||||
let read_pos = *pos;
|
let read_pos = *pos;
|
||||||
// todo(dsherret): should this always set it to the end of the file?
|
// todo(dsherret): should this always set it to the end of the file?
|
||||||
if *pos < self.file.len {
|
if *pos < self.file.offset.len {
|
||||||
// advance the position due to the read
|
// advance the position due to the read
|
||||||
*pos = self.file.len;
|
*pos = self.file.offset.len;
|
||||||
}
|
}
|
||||||
read_pos
|
read_pos
|
||||||
};
|
};
|
||||||
if read_pos > self.file.len {
|
if read_pos > self.file.offset.len {
|
||||||
return Ok(Cow::Borrowed(&[]));
|
return Ok(Cow::Borrowed(&[]));
|
||||||
}
|
}
|
||||||
if read_pos == 0 {
|
if read_pos == 0 {
|
||||||
|
@ -701,7 +717,7 @@ impl FileBackedVfsFile {
|
||||||
.read_file_all(&self.file, VfsFileSubDataKind::Raw)?,
|
.read_file_all(&self.file, VfsFileSubDataKind::Raw)?,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let size = (self.file.len - read_pos) as usize;
|
let size = (self.file.offset.len - read_pos) as usize;
|
||||||
let mut buf = vec![0; size];
|
let mut buf = vec![0; size];
|
||||||
self.vfs.read_file(&self.file, read_pos, &mut buf)?;
|
self.vfs.read_file(&self.file, read_pos, &mut buf)?;
|
||||||
Ok(Cow::Owned(buf))
|
Ok(Cow::Owned(buf))
|
||||||
|
@ -921,7 +937,11 @@ impl FileBackedVfs {
|
||||||
file: &VirtualFile,
|
file: &VirtualFile,
|
||||||
sub_data_kind: VfsFileSubDataKind,
|
sub_data_kind: VfsFileSubDataKind,
|
||||||
) -> std::io::Result<Cow<'static, [u8]>> {
|
) -> std::io::Result<Cow<'static, [u8]>> {
|
||||||
let read_range = self.get_read_range(file, sub_data_kind, 0, file.len)?;
|
let read_len = match sub_data_kind {
|
||||||
|
VfsFileSubDataKind::Raw => file.offset.len,
|
||||||
|
VfsFileSubDataKind::ModuleGraph => file.module_graph_offset.len,
|
||||||
|
};
|
||||||
|
let read_range = self.get_read_range(file, sub_data_kind, 0, read_len)?;
|
||||||
match &self.vfs_data {
|
match &self.vfs_data {
|
||||||
Cow::Borrowed(data) => Ok(Cow::Borrowed(&data[read_range])),
|
Cow::Borrowed(data) => Ok(Cow::Borrowed(&data[read_range])),
|
||||||
Cow::Owned(data) => Ok(Cow::Owned(data[read_range].to_vec())),
|
Cow::Owned(data) => Ok(Cow::Owned(data[read_range].to_vec())),
|
||||||
|
@ -952,19 +972,20 @@ impl FileBackedVfs {
|
||||||
pos: u64,
|
pos: u64,
|
||||||
len: u64,
|
len: u64,
|
||||||
) -> std::io::Result<Range<usize>> {
|
) -> std::io::Result<Range<usize>> {
|
||||||
if pos > file.len {
|
let file_offset_and_len = match sub_data_kind {
|
||||||
|
VfsFileSubDataKind::Raw => file.offset,
|
||||||
|
VfsFileSubDataKind::ModuleGraph => file.module_graph_offset,
|
||||||
|
};
|
||||||
|
if pos > file_offset_and_len.len {
|
||||||
return Err(std::io::Error::new(
|
return Err(std::io::Error::new(
|
||||||
std::io::ErrorKind::UnexpectedEof,
|
std::io::ErrorKind::UnexpectedEof,
|
||||||
"unexpected EOF",
|
"unexpected EOF",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let offset = match sub_data_kind {
|
let file_offset =
|
||||||
VfsFileSubDataKind::Raw => file.offset,
|
self.fs_root.start_file_offset + file_offset_and_len.offset;
|
||||||
VfsFileSubDataKind::ModuleGraph => file.module_graph_offset,
|
|
||||||
};
|
|
||||||
let file_offset = self.fs_root.start_file_offset + offset;
|
|
||||||
let start = file_offset + pos;
|
let start = file_offset + pos;
|
||||||
let end = file_offset + std::cmp::min(pos + len, file.len);
|
let end = file_offset + std::cmp::min(pos + len, file_offset_and_len.len);
|
||||||
Ok(start as usize..end as usize)
|
Ok(start as usize..end as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue