Skip to content

fix(martin): reject invalid scale and inverted bbox in static rendering#2830

Merged
CommanderStorm merged 16 commits into
maplibre:mainfrom
CommanderStorm:static-camera-hardening
May 26, 2026
Merged

fix(martin): reject invalid scale and inverted bbox in static rendering#2830
CommanderStorm merged 16 commits into
maplibre:mainfrom
CommanderStorm:static-camera-hardening

Conversation

@CommanderStorm

@CommanderStorm CommanderStorm commented May 24, 2026

Copy link
Copy Markdown
Member

breaks out one of the items of #2794

Harden request validation on the static map endpoint:

- Scale factor: reject non-finite and non-positive values. `f32::NAN`,
  `f32::NEG_INFINITY`, and negative scales all saturate to `0u8` on the
  `as u8` cast, silently passing the MAX_SCALE check and then feeding
  NaN/Inf into `log2(pixel_ratio)` in the renderer.
- Bounding box: reject inverted boxes (max < min) with a 400 rather than
  rendering a degenerate camera.

Also rename the `static_camera_expected/` fixture directory to
`static_camera/` for consistency with the other static-render fixtures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 24, 2026 23:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Hardens request validation for the static map rendering endpoint by rejecting non-finite/non-positive scale factors and inverted bounding boxes, preventing degenerate inputs from reaching the renderer. Also renames a test fixture directory for consistency.

Changes:

  • Reject scale factors that are NaN, infinite, zero, or negative with 400 Scale factor must be a positive finite number, before the saturating as u8 cast that would otherwise silently coerce them to 0.
  • Reject inverted bounding boxes (max < min on either axis) with 400 Bounding box is inverted: ... before they reach bbox_to_center_zoom.
  • Rename tests/fixtures/static_camera_expected/static_camera/ (pure git mv) and update the single referencing constant.

Reviewed changes

Copilot reviewed 3 out of 10 changed files in this pull request and generated no comments.

File Description
martin/src/srv/styles_static.rs Adds CameraRequest::validate (inverted-bbox check), adds finite/positive scale check before the cast in SizeRequest::validate, wires camera validation into handle_static_request, and adds rstest cases for both new error paths.
martin/tests/styles_rendering_test.rs Updates CAMERA_EXPECTED_DIR constant to CAMERA_DIR to match the renamed fixture directory.
tests/fixtures/static_camera/{bbox_pm30,bearing_90,center_berlin_z4,center_z3,pitch_45}.png Fixture files moved from static_camera_expected/ (byte-identical).

Comment thread martin/src/srv/styles_static.rs Outdated
Comment thread justfile Outdated
Comment thread justfile Outdated
Co-authored-by: Frank Elsinga <frank@elsinga.de>
@CommanderStorm CommanderStorm requested a review from nyurik May 24, 2026 23:48
@CommanderStorm CommanderStorm enabled auto-merge (squash) May 24, 2026 23:57
@github-actions

github-actions Bot commented May 25, 2026

Copy link
Copy Markdown

Performance Comparison mainstatic-camera-hardening

Total Elapsed Time: 70.99s → 70.42s (-0.8%)
CPU Baseline: 81.17µs → 81.40µs (+0.3%)
Benchmark ID: timing

timing - Function execution time metrics.

+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| Function                   | Calls                        | Avg                            | P95                             | Total                          | % Total                      |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| martin::main               | 1 → 1 (+0.0%)                | 70.97s → 70.43s (-0.8%)        | 71.00s → 70.46s (-0.8%)         | 70.99s → 70.42s (-0.8%)        | 100.00% → 100.00% (+0.0%)    |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| martin::start              | 1 → 1 (+0.0%)                | 70.97s → 70.43s (-0.8%)        | 71.00s → 70.46s (-0.8%)         | 70.98s → 70.42s (-0.8%)        | 100.00% → 99.99% (-0.0%)     |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| content::get_tile          | 2200600 → 2200600 (+0.0%)    | 23.06µs → 22.26µs (-3.5%)      | 34.37µs → 33.44µs (-2.7%)       | 50.74s → 48.99s (-3.4%)        | 71.48% → 69.57% (-2.7%)      |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| content::get_http_response | 2200600 → 2200600 (+0.0%)    | 15.81µs → 15.19µs (-3.9%)      | 27.70µs → 27.34µs (-1.3%)       | 34.79s → 33.43s (-3.9%)        | 49.01% → 47.47% (-3.1%)      |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| content::get_tile_content  | 2200600 → 2200600 (+0.0%)    | 13.47µs → 12.36µs (-8.2%)      | 24.91µs → 24.11µs (-3.2%)       | 29.64s → 27.20s (-8.2%)        | 41.76% → 38.62% (-7.5%)      |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| content::new               | 2200600 → 2200600 (+0.0%)    | 2.59µs → 2.20µs (-15.1%)       | 2.04µs → 2.00µs (-2.0%)         | 5.70s → 4.84s (-15.1%)         | 8.03% → 6.88% (-14.3%)       |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| content::recompress        | 2200600 → 2200600 (+0.0%)    | 1.27µs → 1.26µs (-0.8%)        | 141.00ns → 150.00ns (+6.4%)     | 2.80s → 2.78s (-0.7%)          | 3.94% → 3.95% (+0.3%)        |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| source::get_sources        | 2200600 → 2200600 (+0.0%)    | 1.20µs → 1.24µs (+3.3%)        | 1.64µs → 1.66µs (+1.2%)         | 2.64s → 2.74s (+3.8%)          | 3.72% → 3.89% (+4.6%)        |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| content::encode            | 100100 → 100100 (+0.0%)      | 25.86µs → 25.71µs (-0.6%)      | 30.67µs → 30.43µs (-0.8%)       | 2.59s → 2.57s (-0.8%)          | 3.65% → 3.66% (+0.3%)        |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| server::new_server         | 1 → 1 (+0.0%)                | 260.93µs → 259.65µs (-0.5%)    | 260.99µs → 259.71µs (-0.5%)     | 260.95µs → 259.71µs (-0.5%)    | 0.00% → 0.00% (+0.0%)        |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| optimizer::encode          | 1 → 1 (+0.0%)                | 54.64µs → 64.98µs (+18.9%)     | 54.66µs → 64.99µs (+18.9%)      | 54.65µs → 64.97µs (+18.9%)     | 0.00% → 0.00% (+0.0%)        |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| optimizer::encode_into     | 4 → 4 (+0.0%)                | 7.66µs → 9.50µs (+24.0%) ⚠️    | 11.57µs → 24.16µs (+108.8%) ⚠️  | 30.62µs → 38.02µs (+24.2%) ⚠️  | 0.00% → 0.00% (+0.0%)        |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| encode::write_to           | 4 → 4 (+0.0%)                | 7.16µs → 8.23µs (+14.9%)       | 10.54µs → 19.92µs (+89.0%) ⚠️   | 28.64µs → 32.93µs (+15.0%)     | 0.00% → 0.00% (+0.0%)        |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| writer::with               | 72 → 72 (+0.0%)              | 121.00ns → 128.00ns (+5.8%)    | 291.00ns → 320.00ns (+10.0%)    | 8.73µs → 9.22µs (+5.6%)        | 0.00% → 0.00% (+0.0%)        |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+
| optimizer::analyze         | 1 → 1 (+0.0%)                | 7.75µs → 8.39µs (+8.3%)        | 7.75µs → 8.39µs (+8.3%)         | 7.74µs → 8.39µs (+8.4%)        | 0.00% → 0.00% (+0.0%)        |
+----------------------------+------------------------------+--------------------------------+---------------------------------+--------------------------------+------------------------------+

alloc-bytes - Exclusive allocation bytes by each function (excluding nested calls).

+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| Function                       | Calls                        | Avg                             | P95                             | Total                           | % Total                    |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| content::get_tile_content      | 2200600 → 2200600 (+0.0%)    | 91.6 KB → 91.6 KB (+0.0%)       | 180.2 KB → 180.2 KB (+0.0%)     | 192.3 GB → 192.3 GB (+0.0%)     | 84.00% → 84.00% (+0.0%)    |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| content::encode                | 100100 → 100100 (+0.0%)      | 344.5 KB → 344.5 KB (+0.0%)     | 347.2 KB → 347.2 KB (+0.0%)     | 32.9 GB → 32.9 GB (+0.0%)       | 14.37% → 14.37% (+0.0%)    |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| source::get_sources            | 2200600 → 2200600 (+0.0%)    | 1.3 KB → 1.3 KB (+0.0%)         | 2.4 KB → 2.4 KB (+0.0%)         | 2.7 GB → 2.7 GB (+0.0%)         | 1.20% → 1.20% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| content::get_tile              | 2200600 → 2200600 (+0.0%)    | 297 B → 297 B (+0.0%)           | 296 B → 296 B (+0.0%)           | 624.7 MB → 624.7 MB (+0.0%)     | 0.27% → 0.27% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| content::get_http_response     | 2200600 → 2200600 (+0.0%)    | 182 B → 182 B (+0.0%)           | 200 B → 200 B (+0.0%)           | 383.6 MB → 383.6 MB (+0.0%)     | 0.16% → 0.16% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| martin::start                  | 1 → 1 (+0.0%)                | 3.0 MB → 3.0 MB (+0.0%)         | 3.0 MB → 3.0 MB (+0.0%)         | 3.0 MB → 3.0 MB (+0.0%)         | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| martin::main                   | 1 → 1 (+0.0%)                | 164.9 KB → 139.9 KB (-15.2%)    | 165.0 KB → 139.9 KB (-15.2%)    | 164.9 KB → 139.9 KB (-15.2%)    | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| optimizer::encode              | 1 → 1 (+0.0%)                | 67.7 KB → 67.7 KB (+0.0%)       | 67.7 KB → 67.7 KB (+0.0%)       | 67.7 KB → 67.7 KB (+0.0%)       | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| server::new_server             | 1 → 1 (+0.0%)                | 31.1 KB → 31.1 KB (+0.0%)       | 31.1 KB → 31.1 KB (+0.0%)       | 31.1 KB → 31.1 KB (+0.0%)       | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| tile::from_tile                | 4 → 4 (+0.0%)                | 376 B → 376 B (+0.0%)           | 376 B → 376 B (+0.0%)           | 1.5 KB → 1.5 KB (+0.0%)         | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| encode::write_to               | 4 → 4 (+0.0%)                | 370 B → 370 B (+0.0%)           | 624 B → 624 B (+0.0%)           | 1.4 KB → 1.4 KB (+0.0%)         | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| writer::with                   | 72 → 72 (+0.0%)              | 16 B → 16 B (+0.0%)             | 380 B → 380 B (+0.0%)           | 1.2 KB → 1.2 KB (+0.0%)         | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| encode::dict_may_be_beneficial | 4 → 4 (+0.0%)                | 256 B → 256 B (+0.0%)           | 256 B → 256 B (+0.0%)           | 1.0 KB → 1.0 KB (+0.0%)         | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| sort::sort                     | 4 → 4 (+0.0%)                | 120 B → 120 B (+0.0%)           | 160 B → 160 B (+0.0%)           | 480 B → 480 B (+0.0%)           | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+
| writer::write_header           | 4 → 4 (+0.0%)                | 69 B → 69 B (+0.0%)             | 104 B → 104 B (+0.0%)           | 276 B → 276 B (+0.0%)           | 0.00% → 0.00% (+0.0%)      |
+--------------------------------+------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------+

Threads

Total Alloc: 3.0 MB → 3.0 MB (+0.0%)
Total Dealloc: 301.5 MB → 301.5 MB (+0.0%)
Mem Diff: -298.5 MB → -298.5 MB (+0.0%)

+--------+--------------------------+----------------------------+--------------------------------+----------------------------+--------------------------------+
| Thread | CPU % Avg                | CPU % Max                  | Alloc                          | Dealloc                    | Mem Diff                       |
+--------+--------------------------+----------------------------+--------------------------------+----------------------------+--------------------------------+
| martin | 0.00% → 0.00% (+0.0%)    | 12.00% → 11.90% (-0.8%)    | 2.8 MB → 2.8 MB (+0.0%)        | 1.9 MB → 1.9 MB (+0.0%)    | 963.8 KB → 939.2 KB (-2.6%)    |
+--------+--------------------------+----------------------------+--------------------------------+----------------------------+--------------------------------+
| hp-mcp | 0.00% → 0.00% (+0.0%)    | 0.00% → 0.00% (+0.0%)      | 31.7 KB → 54.7 KB (+72.6%) ⚠️  | 3.4 KB → 3.1 KB (-8.8%)    | 28.4 KB → 51.6 KB (+81.7%) ⚠️  |
+--------+--------------------------+----------------------------+--------------------------------+----------------------------+--------------------------------+

Generated with hotpath-rs

CommanderStorm and others added 6 commits May 25, 2026 02:43
TEMPORARY (revert after diagnosis): include the underlying StyleError in
the 500 response body so the coverage-job render-test failures
(bbox/bearing) reveal the real cause in CI logs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The render tests fetched vector tiles live from demotiles:443. The demo
style's source was a TileJSON whose `tiles` field is an absolute
demotiles URL, so tile fetches bypassed the mitmproxy cassette (which
only captured tiles.json + glyphs). Under the coverage job's heavier
concurrent load (whole workspace under llvm-cov, multi-worker pool) the
burst of direct connections to demotiles got reset (SSL_ERROR_SYSCALL),
failing the bbox/bearing renders -- while the lighter live unit-test job
happened to pass.

Give the test style an inline `tiles` source so the existing URL-rewrite
routes tile fetches through the proxy, and re-record the cassette so it
now contains the vector tiles. Renders no longer touch the network
(verified with `--server-replay --set server_replay_extra=kill` on both
render-test binaries). Update the served-style integration snapshots to
match the inline-tiles source.

Also reverts the temporary diagnostic that surfaced the StyleError.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This pool-concurrency unit test rendered the demo style directly (no
proxy rewrite), so it fetched vector tiles live from demotiles. Under
the coverage job's load that burst of connections got reset
(SSL_ERROR_SYSCALL). Render a local inline-GeoJSON style instead: it
needs no network, exercises the multi-worker pool exactly the same, and
works both bare and under the render-cache proxy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CommanderStorm and others added 3 commits May 26, 2026 02:26
Switching the maplibre source from a TileJSON `url` to explicit `tiles`
enlarged the served style; the body fixtures were re-blessed but the
`.headers` etag still pinned the old 1041-byte length.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `Unit test the server` job ran `cargo test --package martin` (rendering
is a default feature) with no proxy, so styles_rendering_test fetched vector
tiles from the live demotiles.maplibre.org upstream. That made the job flake
intermittently (10/21 renders 500ing, ~6min runtime) whenever those fetches
stalled on the runner.

Wrap the martin tests in `just with-render-cache` on Linux so tiles replay
from the committed cassette, matching the coverage job. Verified hermetic:
under server_replay_extra=kill the suite passes 21/21 with zero cassette
misses.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
Comment thread martin-core/src/resources/styles/render_pool.rs Outdated
@github-actions github-actions Bot removed the bless label May 26, 2026
@CommanderStorm CommanderStorm merged commit bc1d064 into maplibre:main May 26, 2026
49 of 51 checks passed
@CommanderStorm CommanderStorm deleted the static-camera-hardening branch May 26, 2026 01:52
@CommanderStorm CommanderStorm mentioned this pull request May 26, 2026
CommanderStorm added a commit that referenced this pull request Jun 16, 2026
## 🤖 New release

* `martin-tile-utils`: 0.7.3 -> 0.7.4 (✓ API compatible changes)
* `mbtiles`: 0.17.6 -> 0.18.0 (⚠ API breaking changes)
* `martin-core`: 0.7.0 -> 0.8.0 (⚠ API breaking changes)
* `martin`: 1.10.1 -> 1.11.0

### ⚠ `mbtiles` breaking changes

```text
--- failure enum_tuple_variant_changed_kind: An enum tuple variant changed kind ---

Description:
A public enum's exhaustive tuple variant has changed to a different kind of enum variant, breaking possible instantiations and patterns.
        ref: https://doc.rust-lang.org/reference/items/enumerations.html
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/enum_tuple_variant_changed_kind.ron

Failed in:
  variant MbtError::InconsistentMetadata in /tmp/.tmpCkABTN/martin/mbtiles/src/errors.rs:39
  variant MbtError::IncorrectTileHash in /tmp/.tmpCkABTN/martin/mbtiles/src/errors.rs:50
  variant MbtError::MissingTileReference in /tmp/.tmpCkABTN/martin/mbtiles/src/errors.rs:59
  variant MbtError::InvalidTileIndex in /tmp/.tmpCkABTN/martin/mbtiles/src/errors.rs:68
  variant MbtError::AggHashMismatch in /tmp/.tmpCkABTN/martin/mbtiles/src/errors.rs:78
  variant MbtError::MismatchedTargetType in /tmp/.tmpCkABTN/martin/mbtiles/src/errors.rs:115
  variant MbtError::AggHashMismatchWithDiff in /tmp/.tmpCkABTN/martin/mbtiles/src/errors.rs:152
  variant MbtError::AggHashMismatchAfterApply in /tmp/.tmpCkABTN/martin/mbtiles/src/errors.rs:162
  variant MbtError::BinDiffIncorrectTileHash in /tmp/.tmpCkABTN/martin/mbtiles/src/errors.rs:177
```

### ⚠ `martin-core` breaking changes

```text
--- failure auto_trait_impl_removed: auto trait no longer implemented ---

Description:
A public type has stopped implementing one or more auto traits. This can break downstream code that depends on the traits being implemented.
        ref: https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/auto_trait_impl_removed.ron

Failed in:
  type StyleSources is no longer UnwindSafe, in /tmp/.tmpCkABTN/martin/martin-core/src/resources/styles/mod.rs:93

--- failure enum_tuple_variant_changed_kind: An enum tuple variant changed kind ---

Description:
A public enum's exhaustive tuple variant has changed to a different kind of enum variant, breaking possible instantiations and patterns.
        ref: https://doc.rust-lang.org/reference/items/enumerations.html
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/enum_tuple_variant_changed_kind.ron

Failed in:
  variant FontError::InvalidFontRangeStartEnd in /tmp/.tmpCkABTN/martin/martin-core/src/resources/fonts/error.rs:19
  variant PmtilesError::UnknownTileType in /tmp/.tmpCkABTN/martin/martin-core/src/tiles/pmtiles/error.rs:23
  variant PostgresError::CannotUseClientKey in /tmp/.tmpCkABTN/martin/martin-core/src/tiles/postgres/errors.rs:40
  variant PostgresError::PostgisTooOld in /tmp/.tmpCkABTN/martin/martin-core/src/tiles/postgres/errors.rs:84
  variant PostgresError::PostgresqlTooOld in /tmp/.tmpCkABTN/martin/martin-core/src/tiles/postgres/errors.rs:93
  variant PostgresError::PrepareQueryError in /tmp/.tmpCkABTN/martin/martin-core/src/tiles/postgres/errors.rs:102

--- failure enum_variant_missing: pub enum variant removed or renamed ---

Description:
A publicly-visible enum has at least one variant that is no longer available under its prior name. It may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/enum_variant_missing.ron

Failed in:
  variant StyleError::SingleThreadedRenderPoolError, previously in file /tmp/.tmpFbd1fK/martin-core/src/resources/styles/error.rs:8
  variant PostgresError::InvalidTableExtent, previously in file /tmp/.tmpFbd1fK/martin-core/src/tiles/postgres/errors.rs:84

--- failure inherent_method_missing: pub method removed or renamed ---

Description:
A publicly-visible method or associated fn is no longer available under its prior name. It may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/inherent_method_missing.ron

Failed in:
  StyleSources::set_rendering_enabled, previously in file /tmp/.tmpFbd1fK/martin-core/src/resources/styles/mod.rs:193
```

<details><summary><i><b>Changelog</b></i></summary><p>


## `mbtiles`

<blockquote>

##
[0.18.0](mbtiles-v0.17.6...mbtiles-v0.18.0)
- 2026-06-16

### Added

- static rendering core
([#2804](#2804))

### Other

- migrate `MBTilesReloader` to be based on `ReloadDriver` and
`Discovery` (pg-reload-6)
([#2853](#2853))
- make sure that error types with multiple identical types have names
([#2832](#2832))
- lockfile maintenance
([#2822](#2822))
- *(deps)* Update `sqlx` to 0.9.0 and adapt MBTiles dynamic SQL to
`SqlSafeStr` ([#2821](#2821))
- update to maplibre_native@8.1
([#2859](#2859))
- add #![forbid(unsafe_code)] to martin-tile-utils
([#2847](#2847))
</blockquote>

## `martin-core`

<blockquote>

##
[0.8.0](martin-core-v0.7.0...martin-core-v0.8.0)
- 2026-06-16

### Added

- Auto-refresh pmtiles source on source data change
([#2858](#2858))
- duckdb-source implementation at martin-core
([#2831](#2831))
- static rendering core
([#2804](#2804))

### Fixed

- *(unstable-cog)* Allow for 0.1% (up to 3m of error at z0) in COGs from
a matching zoom level in WebMercatorQuad
([#2878](#2878))
- *(martin)* reject invalid scale and inverted bbox in static rendering
([#2830](#2830))
- ignore ignored directory for sprite resolution
([#2815](#2815))

### Other

- split out the test code to `test_support`
([#2885](#2885))
- update to maplibre_native@8.1
([#2859](#2859))
- *(pg)* cleanup how extent is handled (PGReloader 0)
([#2837](#2837))
- make sure that error types with multiple identical types have names
([#2832](#2832))
- make the MLN renderer multi threaded
([#2826](#2826))
- cache render fixtures
([#2828](#2828))
</blockquote>

## `martin`

<blockquote>

##
[1.11.0](martin-v1.10.1...martin-v1.11.0)
- 2026-06-16

### Added

- *(pg)* enable Postgres reloading
([#2841](#2841))
- teach ObjectStoreDiscovery to track source data versions
([#2864](#2864))
- Auto-refresh pmtiles source on source data change
([#2858](#2858))
- Add COGReloader and PMTilesReloader (Tile Reload Phase 2)
([#2750](#2750))
- static rendering core
([#2804](#2804))
- duckdb-source implementation at martin-core
([#2831](#2831))

### Fixed

- *(martin)* reject invalid scale and inverted bbox in static rendering
([#2830](#2830))
- Use ST_EstimatedExtent for quick bounds calc
([#1220](#1220))
- ignore ignored directory for sprite resolution
([#2815](#2815))
- *(unstable-cog)* Allow for 0.1% (up to 3m of error at z0) in COGs from
a matching zoom level in WebMercatorQuad
([#2878](#2878))

### Other

- *(deps)* autoupdate pre-commit
([#2896](#2896))
- *(deps)* Bump the all-npm-version-updates group across 2 directories
with 19 updates ([#2889](#2889))
- add tests for how EXACTLY our config system does parsing (config-4)
([#2872](#2872))
- split out the test code to `test_support`
([#2885](#2885))
- move pg fingerprinting to u128
([#2886](#2886))
- split Config types into config.rs, making main/mod.rs a pure mod
(config-3) ([#2876](#2876))
- move parsing to its own module (config-2)
([#2875](#2875))
- extract impl Config to lifecycle module (confgi-1)
([#2874](#2874))
- pg reloader test to reduce the pg-reloader diff
([#2867](#2867))
- rename PmTilesReloader to PmtilesReloader
([#2861](#2861))
- *(deps)* Bump the all-npm-version-updates group across 2 directories
with 18 updates ([#2856](#2856))
- migrate Pmtiles to `ReloadDriver` and `Discovery` (pg-reload-7)
([#2840](#2840))
- migrate `MBTilesReloader` to be based on `ReloadDriver` and
`Discovery` (pg-reload-6)
([#2853](#2853))
- adopt `ReloadDriver`/`Discovery` for Mbtiles (pg-reload-5)
([#2852](#2852))
- move reload-`Trigger`-ing to a separate trait
([#2845](#2845))
- *(deps)* autoupdate pre-commit
([#2849](#2849))
- extract `Sink` trait for the tile-source manager
([#2844](#2844))
- *(pg)* Refactor discovery to enable fingerprinting (PGReloader 2)
([#2835](#2835))
- *(pg)* split auto-discovery into discover + instantiate phases
(PGReloader 1) ([#2836](#2836))
- *(pg)* cleanup how extent is handled (PGReloader 0)
([#2837](#2837))
- make sure that error types with multiple identical types have names
([#2832](#2832))
- fix import ordering drift
([#2838](#2838))
- lockfile maintenance
([#2822](#2822))
- make the MLN renderer multi threaded
([#2826](#2826))
- add a pre-commit to simplify UTF characters
([#2827](#2827))
- update to maplibre_native@8.1
([#2859](#2859))
- cache render fixtures
([#2828](#2828))
- add #![forbid(unsafe_code)] to martin-tile-utils
([#2847](#2847))
- *(deps)* Update `sqlx` to 0.9.0 and adapt MBTiles dynamic SQL to
`SqlSafeStr` ([#2821](#2821))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants