diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 34aae0ae..f8f44055 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -44,6 +44,27 @@ jobs: - run: cargo build --no-default-features --features read_core,wasm - run: cargo build --no-default-features --features doc + cross: + strategy: + matrix: + target: + # A 32-bit target. + - "i686-unknown-linux-gnu" + # A big-endian target + - "mips64-unknown-linux-gnuabi64" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Install rust + run: | + rustup install stable + rustup default stable + - run: cargo install cross + - run: rustup target add ${{matrix.target}} + - run: cross test --target ${{matrix.target}} --features all + msrv-read: runs-on: ubuntu-latest steps: @@ -51,7 +72,7 @@ jobs: with: submodules: true - name: Install rust - run: rustup update 1.42.0 && rustup default 1.42.0 + run: rustup update 1.52.0 && rustup default 1.52.0 - name: Test run: cargo test --verbose --no-default-features --features read,std diff --git a/README.md b/README.md index 19268a95..193a5a7c 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ See [`crates/examples`](crates/examples) for more examples. Changes to MSRV are considered breaking changes. We are conservative about changing the MSRV, but sometimes are required to due to dependencies. The MSRV is: - * 1.42.0 for the `read` feature and its dependencies. + * 1.52.0 for the `read` feature and its dependencies. * 1.56.1 for the `write` feature and its dependencies. ## License diff --git a/crates/examples/src/readobj/elf.rs b/crates/examples/src/readobj/elf.rs index 1bd16f35..a8ed759b 100644 --- a/crates/examples/src/readobj/elf.rs +++ b/crates/examples/src/readobj/elf.rs @@ -361,7 +361,7 @@ fn print_section_symbols( } else { p.field("SectionIndex", shndx); } - if let Some(shndx) = symbols.shndx(index) { + if let Some(shndx) = symbols.shndx(endian, index) { p.field("ExtendedSectionIndex", shndx); } }); diff --git a/crates/examples/testfiles/pe/resource.exe.readobj.0 b/crates/examples/testfiles/pe/resource.exe.readobj.0 new file mode 100644 index 00000000..489b8dc7 --- /dev/null +++ b/crates/examples/testfiles/pe/resource.exe.readobj.0 @@ -0,0 +1,42 @@ +ImageResourceDirectory { + Characteristics: 0 + TimeDateStamp: 0 + MajorVersion: 0 + MinorVersion: 0 + NumberOfNamedEntries: 0 + NumberOfIdEntries: 1 + ImageResourceDirectoryEntry { + NameOrId: RT_VERSION (0x10) + OffsetToDataOrDirectory: 0x80000018 + ImageResourceDirectory { + Characteristics: 0 + TimeDateStamp: 0 + MajorVersion: 0 + MinorVersion: 0 + NumberOfNamedEntries: 1 + NumberOfIdEntries: 0 + ImageResourceDirectoryEntry { + NameOrId: "MY VERSION" (0x80000048) + OffsetToDataOrDirectory: 0x80000030 + ImageResourceDirectory { + Characteristics: 0 + TimeDateStamp: 0 + MajorVersion: 0 + MinorVersion: 0 + NumberOfNamedEntries: 0 + NumberOfIdEntries: 1 + ImageResourceDirectoryEntry { + NameOrId: 1033 + OffsetToDataOrDirectory: 0x60 + ImageResourceDataEntry { + VirtualAddress: 0x10070 + Size: 92 + CodePage: 0 + Reserved: 0x0 + } + } + } + } + } + } +} diff --git a/src/read/elf/symbol.rs b/src/read/elf/symbol.rs index f52eff20..390aa466 100644 --- a/src/read/elf/symbol.rs +++ b/src/read/elf/symbol.rs @@ -4,7 +4,6 @@ use core::fmt::Debug; use core::slice; use core::str; -use crate::elf; use crate::endian::{self, Endianness}; use crate::pod::Pod; use crate::read::util::StringTable; @@ -12,6 +11,7 @@ use crate::read::{ self, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, SectionIndex, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapEntry, SymbolScope, SymbolSection, }; +use crate::{elf, U32}; use super::{FileHeader, SectionHeader, SectionTable}; @@ -28,7 +28,7 @@ where shndx_section: SectionIndex, symbols: &'data [Elf::Sym], strings: StringTable<'data, R>, - shndx: &'data [u32], + shndx: &'data [U32], } impl<'data, Elf: FileHeader, R: ReadRef<'data>> Default for SymbolTable<'data, Elf, R> { @@ -145,8 +145,8 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SymbolTable<'data, Elf, R> { /// Return the extended section index for the given symbol if present. #[inline] - pub fn shndx(&self, index: usize) -> Option { - self.shndx.get(index).copied() + pub fn shndx(&self, endian: Elf::Endian, index: usize) -> Option { + self.shndx.get(index).map(|x| x.get(endian)) } /// Return the section index for the given symbol. @@ -161,7 +161,7 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SymbolTable<'data, Elf, R> { match symbol.st_shndx(endian) { elf::SHN_UNDEF => Ok(None), elf::SHN_XINDEX => self - .shndx(index) + .shndx(endian, index) .read_error("Missing ELF symbol extended index") .map(|index| Some(SectionIndex(index as usize))), shndx if shndx < elf::SHN_LORESERVE => Ok(Some(SectionIndex(shndx.into()))), @@ -369,7 +369,7 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> } } elf::SHN_COMMON => SymbolSection::Common, - elf::SHN_XINDEX => match self.symbols.shndx(self.index.0) { + elf::SHN_XINDEX => match self.symbols.shndx(self.endian, self.index.0) { Some(index) => SymbolSection::Section(SectionIndex(index as usize)), None => SymbolSection::Unknown, }, diff --git a/src/read/pe/resource.rs b/src/read/pe/resource.rs index bfbb609f..cb5d5a5e 100644 --- a/src/read/pe/resource.rs +++ b/src/read/pe/resource.rs @@ -1,7 +1,8 @@ use alloc::string::String; +use core::char; use crate::read::{ReadError, ReadRef, Result}; -use crate::{pe, LittleEndian as LE, U16}; +use crate::{pe, LittleEndian as LE, U16Bytes}; /// The `.rsrc` section of a PE file. #[derive(Debug, Clone, Copy)] @@ -143,20 +144,26 @@ pub struct ResourceName { impl ResourceName { /// Converts to a `String`. pub fn to_string_lossy(&self, directory: ResourceDirectory) -> Result { - let d = self.data(directory)?; - Ok(String::from_utf16_lossy(d)) + let d = self.data(directory)?.iter().map(|c| c.get(LE)); + + Ok(char::decode_utf16(d) + .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER)) + .collect::()) } /// Returns the string unicode buffer. - pub fn data<'data>(&self, directory: ResourceDirectory<'data>) -> Result<&'data [u16]> { + pub fn data<'data>( + &self, + directory: ResourceDirectory<'data>, + ) -> Result<&'data [U16Bytes]> { let mut offset = u64::from(self.offset); let len = directory .data - .read::>(&mut offset) + .read::>(&mut offset) .read_error("Invalid resource name offset")?; directory .data - .read_slice::(&mut offset, len.get(LE).into()) + .read_slice::>(&mut offset, len.get(LE).into()) .read_error("Invalid resource name length") } } diff --git a/testfiles b/testfiles index 894282b3..e61733ee 160000 --- a/testfiles +++ b/testfiles @@ -1 +1 @@ -Subproject commit 894282b32a18cda2b88f8117ce357d98461a0d95 +Subproject commit e61733eec1dddc0429285a01959fea97f2bb974f