visgl / visgl/deck.gl

[Bug] GoogleMapsOverlay crashes when a vector map is temporarily zero-width

Open Beginner friendly
#10,596 0 comments 15 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
14.6k
Forks
2.3k
Avg merge
2d 9h
Merged PRs (30d)
42

Description

Description

Hi! We found a crash in GoogleMapsOverlay when Google Maps briefly reports a vector map with zero width and a positive height.

getViewPropsFromCoordinateTransformer calculates aspect = 0 for that frame. Deck cannot invert the resulting projection matrix, and the reused MapView then throws TypeError: Cannot read properties of null (reading '0').

I reproduced this in deck.gl 9.3.10 and current master at 4059257667f07b379f4c5f019eb88ea20260d5c5 using deck.gl's Google Maps mock and the overlay's normal lifecycle. This resembles #4218, though it occurs in the vector-map coordinate transformer.

Flavors

GoogleMapsOverlay

Expected Behavior

A draw should not throw while either map dimension is zero. Once the map has a visible size again, the next draw can restore the correct projection.

Steps to Reproduce

Add this test to test/modules/google-maps/google-maps-overlay.spec.ts:

test('GoogleMapsOverlay#draw tolerates a zero-width vector map', async () => {
  const map = new mapsApi.Map({
    width: 0,
    height: 600,
    longitude: -122.45,
    latitude: 37.78,
    zoom: 13,
    renderingType: mapsApi.RenderingType.VECTOR
  });
  let resolveDeviceInitialized = () => {};
  const deviceInitialized = new Promise<void>(resolve => {
    resolveDeviceInitialized = resolve;
  });
  const overlay = new GoogleMapsOverlay({
    device,
    interleaved: false,
    onDeviceInitialized: () => resolveDeviceInitialized(),
    layers: [
      new ScatterplotLayer({
        data: [{position: [-122.45, 37.78]}],
        getPosition: datum => datum.position,
        radiusMinPixels: 10
      })
    ]
  });

  overlay.setMap(map);
  await deviceInitialized;

  try {
    expect(() => map.draw()).not.toThrow();
  } finally {
    overlay.finalize();
  }
});

Run:

yarn vitest run --project=headless test/modules/google-maps/google-maps-overlay.spec.ts -t "zero-width vector map"

The test logs deck: Pixel project matrix not invertible and fails with TypeError: Cannot read properties of null (reading '0').

I also ran the mounted overlay through 800x600, 800x0, 0x0, 0x600, and back to 800x600. The current code accepts the zero-height and fully hidden states, then throws at 0x600.

The current calculation guards the height only:

const aspect = height ? width / height : 1;

Guarding both dimensions prevents the invalid projection:

const aspect = width > 0 && height > 0 ? width / height : 1;

After this change, all five size transitions succeed. All 11 tests in google-maps-overlay.spec.ts, including the regression test, pass on 9.3.10 and current master.

Environment
  • Framework version: deck.gl 9.3.10 and master at 4059257667f07b379f4c5f019eb88ea20260d5c5
  • Browser: Chromium 147 through deck.gl's headless Vitest project
  • OS: macOS
Logs
deck: Pixel project matrix not invertible
TypeError: Cannot read properties of null (reading '0')

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in the vector-map coordinate transformer used by GoogleMapsOverlay and inspect getViewPropsFromCoordinateTransformer, especially its aspect calculation. Run yarn vitest run --project=headless test/modules/google-maps/google-maps-overlay.spec.ts -t "zero-width vector map" and verify that the regression test and all 11 tests pass without a draw-time exception during zero-sized map states.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, testing
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
90/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.