mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-07 13:23:29 +00:00
* Add craft-vectorcraft-format: the .vectorcraft envelope, with the document as a type parameter File<D>, Head and Image hold the members VectorCraft writes, in its order, with its skip rules: serde_json output of a File<D> is the JSON VectorCraft writes, compact or pretty. Tail places entries after the JSON from version 4 (INLINE_MAX bytes or more, after BLOB_MAGIC), and split_tail and Image::bytes read them back. The crate also has the version and name constants, check() for the format name and newer versions, sniff() for plain and gzip files (the top-level "format" member must be vectorcraft or drawcraft), and standard base64. No dependency on any app; builds for wasm32-unknown-unknown. * ci: do not keep the checkout token in the vectorcraft-format workflow The checkout step sets persist-credentials: false, as jpeg.yml and media.yml do. No later step in the job uses the token. * vectorcraft-format: limit the bytes copied from the data after the JSON Entries::bytes reads a file's entries and returns Error::TooBig once the blob ranges it has copied add up to more than the data after the JSON holds, so entries that name the same bytes again and again are refused, as VectorCraft's reader refuses them. A generator, preview or pdf of the wrong shape now reads as None in File and Head, as VectorCraft opens such a file. File::tail gives a Tail for the file's own version. * ci: pin actions/checkout by commit and Rust to 1.95 in the vectorcraft-format workflow * vectorcraft-format: document that base64 decode ignores the bits before the padding decode reads a group such as Zh== like Zg==, and Zm9= like Zm8=, as VectorCraft's own base64_decode does. The doc comment says so, and a test pins both cases to the canonical bytes. * vectorcraft-format: entries naming the same range share one buffer VectorCraft's reader keeps the bytes of each [offset, length] it has read and gives a repeated entry the same buffer without counting it again (crates/format/src/unpack.rs). Entries::bytes refused such a file once the repeats passed the size of the data after the JSON. It now returns Arc<[u8]>, caches each range, and counts it once. Overlapping ranges that differ are still copied and counted each time. * vectorcraft-format: a refused entry does not count against the copy limit Entries::bytes added a refused entry's length to the bytes copied, so a later entry that fit was refused too. It now counts an entry only once it is read. * vectorcraft-format: Contents reads the document without keeping the preview and PDF File<D> checks the shape of generator, preview and pdf by holding each value in memory, and keeps the preview and PDF base64 it reads. Contents<D> reads format, version, profiles, document and images, and skips the other three as the JSON is read. It accepts and refuses the same files as File<D>. * vectorcraft-format: Contents reads a repeated generator, preview or pdf VectorCraft opens a file whose generator, preview or pdf member is repeated, since its reader does not declare those members, and refuses a repeated format, version, profiles, document or images. Contents now leaves the three members undeclared, so serde skips every copy of them, and still refuses the other repeated members. File and Head are unchanged. * vectorcraft-format: sniff decodes JSON escapes in the format member serde_json reads a file whose format key or value is written with escapes, such as \u0066ormat, as a VectorCraft file, and sniff compared the raw bytes and refused it. sniff now decodes the key and the value before comparing them. * vectorcraft-format: File::read and Contents::read check the version File::read and Contents::read are the readers of a file's JSON. Both refuse another format or a version newer than VERSION after the JSON reads, with ReadError::Envelope holding the Error (Format or TooNew), and return ReadError::Json otherwise. File and Contents no longer implement Deserialize, so a reader cannot skip the check. Both read one implementation and treat repeated members the same way: a repeated generator, preview or pdf is accepted, and File keeps the last value, as serde_json reads a repeated key into a Value. A repeated format, version, document, images or profiles is refused. A top-level array holds format, version, document, images and profiles in that order, as VectorCraft reads it; Contents' fields follow that order. - Image::bytes returns None for an entry of more than MAX_ENTRY (1 GiB, VectorCraft's limit on one entry of a compressed file), and Image::bytes_at_most takes another limit. Entries keeps no per-entry limit, as VectorCraft opens larger entries in uncompressed files. - Entries::blob reads a range; Entries returns Arc<Vec<u8>>. - marker_at finds BLOB_MAGIC where the writer puts it in a file's first bytes; split_tail uses it. - File, Contents, Head, Image, Part and ReadError are #[non_exhaustive].
36 lines
1.4 KiB
YAML
36 lines
1.4 KiB
YAML
name: VectorCraft format
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
push:
|
|
branches: [main]
|
|
paths: ['crates/vectorcraft-format/**', 'Cargo.toml', 'Cargo.lock', '.github/workflows/vectorcraft-format.yml']
|
|
pull_request:
|
|
paths: ['crates/vectorcraft-format/**', 'Cargo.toml', 'Cargo.lock', '.github/workflows/vectorcraft-format.yml']
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
vectorcraft-format:
|
|
timeout-minutes: 15
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# macOS runners are kept for releases: macOS runs only when started by hand.
|
|
os: ${{ github.event_name == 'workflow_dispatch' && fromJSON('["ubuntu-latest","windows-latest","macos-latest"]') || fromJSON('["ubuntu-latest","windows-latest"]') }}
|
|
runs-on: ${{ matrix.os }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable
|
|
with:
|
|
toolchain: "1.95"
|
|
components: rustfmt, clippy
|
|
targets: wasm32-unknown-unknown
|
|
- run: cargo fmt --check
|
|
- run: cargo clippy -p craft-vectorcraft-format --all-targets --locked -- -D warnings
|
|
- run: cargo test -p craft-vectorcraft-format --locked -- --nocapture
|
|
- run: cargo check -p craft-vectorcraft-format --locked --target wasm32-unknown-unknown
|