This commit is contained in:
Robin Appelman 2023-06-08 18:53:23 +02:00
commit 377e1773c0
14 changed files with 2683 additions and 32 deletions

43
.github/workflows/ci.yaml vendored Normal file
View file

@ -0,0 +1,43 @@
name: "CI"
on:
pull_request:
push:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with:
name: ci
instance: https://cache.icewind.me
authToken: '${{ secrets.ATTIC_TOKEN }}'
- run: nix build .#check
clippy:
runs-on: ubuntu-latest
needs: check
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with:
name: ci
instance: https://cache.icewind.me
authToken: '${{ secrets.ATTIC_TOKEN }}'
- run: nix build .#clippy
test:
runs-on: ubuntu-latest
needs: check
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v20
- uses: icewind1991/attic-action@v1
with:
name: ci
instance: https://cache.icewind.me
authToken: '${{ secrets.ATTIC_TOKEN }}'
- run: nix build .#test

2
.gitignore vendored
View file

@ -1,5 +1,3 @@
/target /target
Cargo.lock
data
.direnv .direnv
result result

2278
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

BIN
data/barrel01.dx90.vtx Normal file

Binary file not shown.

BIN
data/barrel01.mdl Normal file

Binary file not shown.

BIN
data/barrel01.vvd Normal file

Binary file not shown.

54
flake.lock generated
View file

@ -1,26 +1,72 @@
{ {
"nodes": { "nodes": {
"naersk": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1686242667,
"narHash": "sha256-I7Kwp06WX/9E+rEND1i1wjdKQQm3XiDxYOyNK9fuJu0=",
"owner": "icewind1991",
"repo": "naersk",
"rev": "6d245a3bbb2ee31ec726bb57b9a8b206302e7110",
"type": "github"
},
"original": {
"owner": "icewind1991",
"repo": "naersk",
"rev": "6d245a3bbb2ee31ec726bb57b9a8b206302e7110",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1670276674, "lastModified": 1686059680,
"narHash": "sha256-FqZ7b2RpoHQ/jlG6JPcCNmG/DoUPCIvyaropUDFhF3Q=", "narHash": "sha256-sp0WlCIeVczzB0G8f8iyRg3IYW7KG31mI66z7HIZwrI=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "52e3e80afff4b16ccb7c52e9f0f5220552f03d04", "rev": "a558f7ac29f50c4b937fb5c102f587678ae1c9fb",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",
"ref": "release-22.11", "ref": "nixos-23.05",
"type": "indirect" "type": "indirect"
} }
}, },
"root": { "root": {
"inputs": { "inputs": {
"naersk": "naersk",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay",
"utils": "utils" "utils": "utils"
} }
}, },
"rust-overlay": {
"inputs": {
"flake-utils": [
"utils"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1686191569,
"narHash": "sha256-8ey5FOXNms9piFGTn6vJeAQmSKk+NL7GTMSoVttsNTs=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "b4b71458b92294e8f1c3a112d972e3cff8a2ab71",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"utils": { "utils": {
"locked": { "locked": {
"lastModified": 1667395993, "lastModified": 1667395993,

View file

@ -1,21 +1,62 @@
{ {
inputs = { inputs = {
nixpkgs.url = "nixpkgs/nixos-23.05";
utils.url = "github:numtide/flake-utils"; utils.url = "github:numtide/flake-utils";
nixpkgs.url = "nixpkgs/release-22.11"; naersk.url = "github:icewind1991/naersk?rev=6d245a3bbb2ee31ec726bb57b9a8b206302e7110";
naersk.inputs.nixpkgs.follows = "nixpkgs";
rust-overlay.url = "github:oxalica/rust-overlay";
rust-overlay.inputs.nixpkgs.follows = "nixpkgs";
rust-overlay.inputs.flake-utils.follows = "utils";
}; };
outputs = { outputs = {
self, self,
nixpkgs, nixpkgs,
utils, utils,
naersk,
rust-overlay,
}: }:
utils.lib.eachDefaultSystem (system: let utils.lib.eachDefaultSystem (system: let
overlays = [ (import rust-overlay) ];
pkgs = (import nixpkgs) { pkgs = (import nixpkgs) {
inherit system; inherit system overlays;
}; };
lib = pkgs.lib;
naersk' = pkgs.callPackage naersk {};
src = lib.sources.sourceByRegex (lib.cleanSource ./.) ["Cargo.*" "(src|benches|tests|examples|data)(/.*)?"];
nearskOpt = {
pname = "vmdl";
root = src;
};
exampleBuildInputs = with pkgs; [
freetype
pkgconfig
cmake
fontconfig
xorg.libX11
xorg.libXcursor
xorg.libXrandr
xorg.libXi
glew-egl
egl-wayland
libGL
openssl
];
in rec { in rec {
# `nix develop` packages = {
devShell = pkgs.mkShell { check = naersk'.buildPackage (nearskOpt // {
mode = "check";
});
clippy = naersk'.buildPackage (nearskOpt // {
mode = "clippy";
});
test = naersk'.buildPackage (nearskOpt // {
release = false;
mode = "test";
nativeBuildInputs = exampleBuildInputs;
});
};
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [ nativeBuildInputs = with pkgs; [
rustc rustc
cargo cargo
@ -25,19 +66,7 @@
clippy clippy
cargo-audit cargo-audit
cargo-msrv cargo-msrv
freetype ] ++ exampleBuildInputs;
pkgconfig
cmake
fontconfig
xorg.libX11
xorg.libXcursor
xorg.libXrandr
xorg.libXi
glew-egl
egl-wayland
libGL
openssl
];
LD_LIBRARY_PATH = with pkgs; "/run/opengl-driver/lib/:${lib.makeLibraryPath ([libGL libGLU])}"; LD_LIBRARY_PATH = with pkgs; "/run/opengl-driver/lib/:${lib.makeLibraryPath ([libGL libGLU])}";
}; };

258
fuzz/Cargo.lock generated Normal file
View file

@ -0,0 +1,258 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "approx"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278"
dependencies = [
"num-traits",
]
[[package]]
name = "arbitrary"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29d47fbf90d5149a107494b15a7dc8d69b351be2db3bb9691740e88ec17fd880"
[[package]]
name = "arrayvec"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytemuck"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fe233b960f12f8007e3db2d136e3cb1c291bfd7396e384ee76025fc1a3932b4"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "cc"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cgmath"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317"
dependencies = [
"approx",
"num-traits",
]
[[package]]
name = "either"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "jobserver"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
dependencies = [
"libc",
]
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "libfuzzer-sys"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8fff891139ee62800da71b7fd5b508d570b9ad95e614a53c6f453ca08366038"
dependencies = [
"arbitrary",
"cc",
"once_cell",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]]
name = "proc-macro2"
version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
"proc-macro2",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
dependencies = [
"once_cell",
]
[[package]]
name = "unicode-ident"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "vmdl"
version = "0.1.0"
dependencies = [
"arrayvec",
"bitflags",
"bytemuck",
"cgmath",
"itertools",
"static_assertions",
"thiserror",
"tracing",
]
[[package]]
name = "vmdl-fuzz"
version = "0.0.0"
dependencies = [
"libfuzzer-sys",
"vmdl",
]

View file

@ -55,7 +55,7 @@ impl Model {
.body_parts .body_parts
.iter() .iter()
.flat_map(|part| part.models.iter()) .flat_map(|part| part.models.iter())
.flat_map(|model| model.lods.iter().next()) .flat_map(|model| model.lods.first())
.flat_map(|lod| lod.meshes.iter()); .flat_map(|lod| lod.meshes.iter());
vtx_meshes vtx_meshes
@ -81,10 +81,10 @@ impl Model {
} }
} }
fn read_indexes<'a, I: Iterator<Item = usize> + 'static, T: Readable>( fn read_indexes<I: Iterator<Item = usize> + 'static, T: Readable>(
indexes: I, indexes: I,
data: &'a [u8], data: &[u8],
) -> impl Iterator<Item = Result<T, ModelError>> + 'a { ) -> impl Iterator<Item = Result<T, ModelError>> + '_ {
indexes indexes
.map(|index| { .map(|index| {
data.get(index..).ok_or_else(|| ModelError::OutOfBounds { data.get(index..).ok_or_else(|| ModelError::OutOfBounds {

View file

@ -26,7 +26,7 @@ impl Mdl {
body_parts: header body_parts: header
.body_part_indexes() .body_part_indexes()
.map(|index| { .map(|index| {
let data = data.get(index..).ok_or_else(|| ModelError::OutOfBounds { let data = data.get(index..).ok_or(ModelError::OutOfBounds {
data: "BodyPart", data: "BodyPart",
offset: index, offset: index,
})?; })?;

View file

@ -204,7 +204,7 @@ bitflags! {
impl StudioHeader { impl StudioHeader {
pub fn header2_index(&self) -> Option<usize> { pub fn header2_index(&self) -> Option<usize> {
(self.studio_hdr2_index > 0) (self.studio_hdr2_index > 0)
.then(|| self.studio_hdr2_index) .then_some(self.studio_hdr2_index)
.and_then(|index| usize::try_from(index).ok()) .and_then(|index| usize::try_from(index).ok())
} }

View file

@ -32,10 +32,10 @@ impl Vvd {
let fixup = fixup?; let fixup = fixup?;
let from = fixup.source_vertex_id as usize; let from = fixup.source_vertex_id as usize;
let to = (fixup.source_vertex_id.saturating_add(fixup.vertex_count)) as usize; let to = (fixup.source_vertex_id.saturating_add(fixup.vertex_count)) as usize;
vertices.extend_from_slice(&source_vertices.get(from..to).ok_or_else(|| { vertices.extend_from_slice(source_vertices.get(from..to).ok_or({
ModelError::OutOfBounds { ModelError::OutOfBounds {
data: "source_vertices", data: "source_vertices",
offset: to as usize, offset: to,
} }
})?); })?);
} }

View file

@ -2,7 +2,6 @@ use std::fs::read;
use vmdl::mdl::Mdl; use vmdl::mdl::Mdl;
use vmdl::vtx::Vtx; use vmdl::vtx::Vtx;
use vmdl::vvd::Vvd; use vmdl::vvd::Vvd;
use vmdl::Model;
#[test] #[test]
fn parse_mdl() { fn parse_mdl() {