Commit Graph
117 Commits
Author SHA1 Message Date
aiongg 71aaf18818 Integration: GPX attributes use decoded_and_normalized_value (deprecated method fails clippy) 2026-10-31 03:09:09 +00:00
aiongg 56c842d8fe Merge track r3-t09
# Conflicts:
#	docs/parity-checklist.md
#	docs/raw-parity.md
#	docs/ui-parity.md
#	docs/whats-new.md
2026-10-31 02:31:25 +00:00
aiongg e05c4f7e7c Merge track r3-t08
# Conflicts:
#	crates/meta/README.md
#	crates/ui-egui/locales/cs.json
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fi.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/id-formats.json
#	crates/ui-egui/locales/id.json
#	crates/ui-egui/locales/it.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/ka-formats.json
#	crates/ui-egui/locales/ka.json
#	crates/ui-egui/locales/pl.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/sv-formats.json
#	crates/ui-egui/locales/sv.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/vi.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
#	crates/ui-egui/src/panels/grid.rs
#	crates/ui-egui/tests/it/main.rs
#	docs/gaps.md
#	docs/library-shortcuts.md
#	docs/parity-checklist.md
#	docs/raw-parity.md
#	docs/user/guides/export-photos.md
#	docs/whats-new.md
2026-10-31 02:31:16 +00:00
aiongg 1f111b5e80 Merge track r3-t07
# Conflicts:
#	crates/engine/src/tests/libops.rs
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-31 02:30:21 +00:00
aiongg b500ddadd0 Integration: #2605 use unsigned_abs for the written UTC offset and skip offsets beyond 18 h; test with i16::MIN 2026-10-31 02:22:42 +00:00
aiongg 42e1685b3a Merge PR #3367: Reject multiple GPX document roots 2026-10-31 02:10:50 +00:00
aiongg bfb9572eb1 Merge PR #2529: LR-MAP-TRACKLOG: Decode XML character references in GPX
docs/gaps.md, docs/whats-new.md, docs/parity-checklist.md: both sides' header items, entries and rows kept.
2026-10-31 02:10:14 +00:00
aiongg b28ef86773 Merge PR #2724: fix(codecs): validate JPEG ICC APP2 chunk sequences
Conflicts: docs/gaps.md header merged (newer date, both change lists), rows kept; other docs unioned
2026-10-31 02:09:46 +00:00
aiongg cc4471d472 Merge PR #3371: Ignore negative XMP pixel dimensions 2026-10-31 02:08:31 +00:00
aiongg a13d7dd47d Merge PR #3242: Reject EXIF offsets beyond 18 hours 2026-10-31 02:08:31 +00:00
aiongg 035d4d5dcb Merge PR #2977: LR-META-EXIF-FULL: reject malformed EXIF clocks
docs/gaps.md, docs/parity-checklist.md, docs/whats-new.md: both sides kept; the PR's sentences added to main's rows and entries.
docs/xmp-interop.md: capture-time paragraph combines both sides.
The PR's test file crates/engine/src/tests_import.rs landed in crates/engine/src/tests/import.rs (moved on main).
2026-10-31 02:08:25 +00:00
aiongg 60e730c3df Merge PR #2712: Never crash: NaN in tone curves and an i16::MIN UTC offset (#2579 items 3 and 4) 2026-10-31 02:08:23 +00:00
aiongg e967200f0d Merge PR #2912: Reject incomplete ISO timestamps in metadata and track logs
crates/meta/src/xmp.rs: kept main's 'mod tests;'; the PR's two tests ported to xmp/tests.rs.
docs/gaps.md, docs/parity-checklist.md, docs/whats-new.md: both sides kept; newer date in headers; XMP row and header carry the PR's sentence.
2026-10-31 02:07:55 +00:00
aiongg 020622aadf Merge PR #2776: Reject signed numeric character references in XML entity decoding
crates/meta/src/xmp.rs: kept main's 'mod tests;' (tests moved to xmp/tests.rs); PR's new test ported there.
2026-10-31 02:06:49 +00:00
aiongg 6c8bcf8a29 Merge PR #2771: Read Canon maker-note lens when LensModel is missing 2026-10-31 02:06:36 +00:00
aiongg 8c96803360 Merge PR #2717: Never crash: rational tag lists show 16 values like every other list (#2579 item 7) 2026-10-31 02:06:36 +00:00
aiongg 9a98d40575 Merge PR #2605: Write capture time UTC offset and sub-seconds in write_exif 2026-10-31 02:06:35 +00:00
aiongg 0c264a6a49 Merge PR #2290: #2284: read the Exif and XMP items of HEIF files 2026-10-31 02:06:35 +00:00
Brandon Thomas bdb146be43 Merge PR #2833 2026-10-30 15:24:30 -04:00
Max MittelstädtandGPT-6-Luna 4e7d0a6282 Ignore negative XMP pixel dimensions
Found while testing crates/meta/src/xmp.rs:550

Co-Authored-By: GPT-6-Luna <noreply@openai.com>
2026-10-30 06:52:49 +00:00
Max MittelstädtandGPT-6-Luna 4c4d322bec Reject multiple GPX document roots
Found while testing crates/meta/src/gpx.rs:111

Co-Authored-By: GPT-6-Luna <noreply@openai.com>
2026-10-30 06:15:05 +00:00
Max MittelstädtandGPT-6-Luna e981b25e06 Reject EXIF offsets beyond 18 hours
Found while testing crates/meta/src/datetime.rs:77

Co-Authored-By: GPT-6-Luna <noreply@openai.com>
2026-10-28 12:07:28 +00:00
eliets2 3833c37a75 review: read Canon LensModel (0x0095) for the maker-note lens fallback
- tag 0x0001 is CameraSettings (numeric LensType at index 22), not an ASCII name; real EOS 5D files never carry a lens name there
- read the lens name from 0x0095 (LensModel) and yield none when only the numeric LensType exists
- fixture now builds a representative maker note (CameraSettings table + LensType 178) and covers both byte orders plus the nameless case
2026-10-28 07:56:50 +02:00
eliets2 9db9811759 Read Canon maker-note lens when LensModel is missing
LightCraft already fills a missing lens_model from the Panasonic and Nikon maker notes in try_read_exif, but never from the Canon maker note, so Canon bodies such as the EOS 5D that omit EXIF LensModel cannot match any lens profile even when the maker note records the lens.

Add a canon_maker_note_lens fallback in try_read_exif, parsed with lightcraft_tiff::makernote::parse_makernote (Canon notes are the Plain kind), mirroring panasonic_maker_note_lens; add a unit test in exif.rs that feeds an Exif block with a Canon maker note but no LensModel and asserts lens_model is populated.

Test: canon_maker_note_lens_fills_lens_model failed before the change and passes after.
2026-10-28 07:56:50 +02:00
Dylan M. Taylor 38c3232214 refactor(meta): isolate descriptive metadata merging 2026-10-28 03:24:18 +00:00
tecari0andClaude Sonnet 5.5 3ae66b2d2f Merge main into fix-2284-heif-exif
Resolve the conflict in the crates/meta/src/lib.rs doc comment: list
both PSD/PSB (from main) and HEIF/HEIC/AVIF (from this branch).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 15:15:45 -07:00
aiongg d151df0149 style: cargo fmt the moved test modules 2026-10-26 18:30:36 +00:00
aiongg 55c9eac7c7 refactor(lightcraft-meta): move focus.rs tests to crates/meta/src/focus/tests.rs 2026-10-26 18:15:50 +00:00
aiongg 03e3b947dc refactor(lightcraft-meta): move xmp.rs tests to crates/meta/src/xmp/tests.rs 2026-10-26 18:15:50 +00:00
Dylan M. Taylor 3022baa861 security(raw,meta): follow-ups from review
An oversized CR3 candidate is skipped without ending the search, repeated child IFD references count once toward the pending cap, deflated chunks lay their rows out as the unpacker reads them (16-bit words, 32-bit word alignment), the tile grid's nominal size is checked against the image before anything is decoded, chunk grouping saturates, and the XMP flattened-key budget is document-wide. The JPEG-header test now parses a real header.
2026-10-25 16:12:03 -04:00
Dylan M. Taylor d8ceb3a6af security/meta,merge,raw,tiff,denoise: bound memory sized by attacker-shaped inputs
XMP flattening, sparse-focus EXIF decode (plus the maker-note and TIFF value
budgets), lossy-DNG chunk staging, panorama stitch frames, the reference ONNX
executor's tensors and the denoise product reader all now reject or cap what a
malformed file can make them allocate: each result is checked before the
memory behind it is reserved, every regression carrying a test that fails
without its bound.
2026-10-25 15:42:19 -04:00
ronibalthazar a1e1b4cc0e LR-META-EXIF-FULL: reject malformed EXIF clocks 2026-10-25 19:03:33 +00:00
ronibalthazar 0352b420a7 fix(codecs): validate JPEG ICC APP2 chunk sequences 2026-10-25 14:13:58 +00:00
ronibalthazar 07d1f0ad5d LR-META-XMP: reject incomplete ISO timestamps 2026-10-25 06:35:43 +00:00
NetterSilverandClaude Haiku 5.5 4ef14cc4b3 Strip trailing NULs from non-UTF-8 IPTC text
Found while testing crates/meta/src/iptc.rs:8 (decode)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 20:38:36 +02:00
NetterSilverandClaude Haiku 5.5 e0519d4300 Reject signed numeric character references in XML entity decoding
Found while testing crates/meta/src/xmp.rs:184 (entity); the same pattern is in crates/lensdb/src/xml.rs:45 and crates/engine/src/preset_luminar.rs:90

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 06:02:56 +00:00
francoisgnandClaude Opus 5.5 144d900c21 Merge upstream/main (integration batch 43, #2729, #2737, #2412) into round3a-integration
Conflicts:
- apps/lightcraft/src/native_menu.rs: upstream's item swapping (macOS keys
  given up for real, Help menu not swapped, Settings / Quit tracked) with
  KEY-GRID's keymap-aware rows. `Item.label` stays the text the row shows
  (native_item_presentation), so `Item::native_label` reuses it instead of
  formatting it again; Settings / Quit store theirs through
  display_item_label, as upstream's native_label did. No early return after
  a rebuild (upstream).
- crates/ui-egui/src/i18n.rs: upstream's tests (#2729: one test per check
  across languages, gaps reported, never a failure) plus the batch's two new
  ones (dropped-photos notice, Polish counts); production code as merged.
- grid.rs, keyword_list.rs, masking.rs: the translation tests #2729 removed
  stay removed; the batch's new keyword and segmenter tests stay.
- cmd/library.rs, ui-egui/src/lib.rs: both test modules, each with its
  #[cfg(test)].
- xtask/src/main.rs: #2302's test_selected and upstream's translation_gaps.
- docs: tracker / gap rows take both sides' edits, headers list both sides'
  changes, history rows of both sides newest-first. What's New: one section
  per date, newest first (the batch had 10-22 above 10-23, and second 10-21
  and 10-19 sections); no line lost.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 02:26:48 +03:00
Brandon Thomas 1acd2938ea Merge PR #2546
# Conflicts:
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-23 17:21:18 -04:00
Brandon Thomas bbf9b713f2 Merge PR #2526
# Conflicts:
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-23 17:21:17 -04:00
francoisgnandClaude Opus 5.5 f74178cdae Merge upstream/main (#2710 one test binary per crate, #2713) into round3a-integration
Conflicts:
- xtask/src/main.rs: upstream's runners (cargo test or nextest, no
  examples, doctests apart, one wasm `cargo check --keep-going`) with
  #2302's `ci --quick` on top: test_selected builds the same targets
  (--lib --bins --tests), the wasm check takes the changed crates in one
  call, the full test step is upstream's.
- apps/lightcraft/src/control_server.rs: upstream's `before` closure, with
  the batch's no-delay sockets kept.
- docs/parity-checklist.md: LR-BEHAV-ACCESS from main (tests/it path),
  LR-BEHAV-LOCALE / LR-BEHAV-LOCALIZE from the batch (Polish).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 21:06:33 +03:00
aiongg f3bb7a9f30 CI: one test binary per crate, line tables only, one WASM check (#2710)
* CI: dev profile keeps line tables for workspace crates and no debug info for dependencies

* Control server tests: persistent_requests_and_slow_replies_outlive_the_idle_read_timeout no longer races the idle timeout

Each request (and the closing half-shutdown) reaches the socket before the
worker reads, so on a slow machine only the reply waits outlast the 100 ms
idle timeout, as the test intends. The idle test sends its input the same
way, and the no-frames test allows 5 s instead of 2 s to give up.

* CI: one integration-test binary per crate

Each crate's tests/*.rs become modules of tests/it/main.rs (51 test files
into 13 binaries, plus 6 that stay their own). Inner #![cfg] attributes
move to the mod lines. Files that change state for the whole process keep
a binary of their own: codecs jxl_tail_heap and raw sr2_heap (dhat global
allocator), gpu shutdown, shutdown_first and memory, ui-egui shutdown.
Docs, comments and the GPU probe name the new paths and targets
(--test it <module>::); the CI report names an it binary's skips after
the crate.

* CI: tests under nextest, doctests apart, one wasm check

xtask ci runs the tests with cargo nextest run --lib --bins --tests when
cargo-nextest is installed, else cargo test with the same targets and a
one-line notice; doctests run after them with cargo test --workspace --doc.
The heif and hardware GPU steps use the same runner. Examples stay out of
the test build (clippy --all-targets still checks them). Concurrent tests
under nextest follow the RUST_TEST_THREADS cap (NEXTEST_TEST_THREADS).
The wasm check is one cargo check --keep-going over the same crates, and
clippy runs with --keep-going.

* CI: tests run under cargo test by default, nextest with LIGHTCRAFT_NEXTEST=1 (per-process scene cache)
2026-10-23 13:34:30 -04:00
darthnutandClaude Opus 5.5 84951ff579 Never crash: rational tag lists show 16 values like every other list (#2579)
The tag panel writes a list as its first 16 values and a count (`list`), but RATIONAL and
SRATIONAL arrays were formatted and joined whole, so a tag holding millions of fractions
became a string as long. They now go through the same cap (`list_with`, which formats only
the values it shows). Item 7 of #2579.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 10:07:47 -07:00
darthnutandClaude Opus 5.5 8b3ce31b66 Never crash: a UTC offset of i16::MIN formats and validates without overflow (#2579)
DateTime deserializes with public fields, so its offset can arrive without passing
valid(). `i16::MIN.abs()` overflows: a panic in debug builds and a negative minute count
in release, which to_iso() then printed. valid() and to_iso() use unsigned_abs().
Item 4 of #2579.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 09:31:29 -07:00
NetterSilverandClaude Haiku 5.5 7fcd2b8c99 Write capture time UTC offset and sub-seconds in write_exif
Found while testing crates/meta/src/exif.rs:462 (write_exif; compare the reader in from_tiff at crates/meta/src/exif.rs:96-107)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 17:32:10 +00:00
ronibalthazar 36d6762f08 #2519: reject invalid UTF-8 in PSD XMP resources 2026-10-22 16:15:39 +01:00
ronibalthazar 26a24eb22e Fail closed on malformed PSD XMP and duplicate resources 2026-10-22 15:48:40 +01:00
ronibalthazar d18fb06aa8 Fail closed on malformed PSD EXIF during extraction 2026-10-22 14:59:39 +01:00
ronibalthazar c8390afbd2 Fail closed on malformed PSD metadata during original export 2026-10-22 14:21:32 +01:00
ronibalthazar 6413bccbfd #2519: read PSD and PSB metadata 2026-10-22 11:20:53 +01:00
NetterSilverandClaude Opus 5.5 0cdbc6c15a Write exact 1/N EXIF ExposureTime for fast shutter speeds
Found while testing crates/meta/src/exif.rs:483 (write_exif, the `r` helper; via lightcraft_tiff::writer::rational at crates/tiff/src/writer.rs:261)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 09:25:00 +00:00