Closed kbauhausness closed 5 years ago
Flagging the current getImageData
implementation:
May be worth exploring get-pixels
's canvas-less, node implementation https://github.com/scijs/get-pixels/blob/master/node-pixels.js
Is TinySDF also affected? TinySDF is used for rendering ideographic characters using client-side fonts.
https://github.com/mapbox/tiny-sdf/blob/34a06b10e99555a156e4d147ab28fd11da4bd4e0/index.js#L40
Is TinySDF also affected?
It looks like it is. It's using the same function of canvas
API.
It definitely blocks local ideograph generation as well. I just tested it out to be sure.
It looks like the ImageData
interface may be what we need to avoid this.
Creates an
ImageData
object from a givenUint8ClampedArray
and the size of the image it contains. If no array is given, it creates an image of a black rectangle. Note that this is the most common way to create such an object in workers ascreateImageData()
is not available there.
EDIT: Ooops, misread the description. This won't work.
cc @asheemmamoowala @mourner Is this what you had in mind?
@ryanhamley no, that's the whole point of TinySDF — we need to use getImageData
to get the data drawn on the canvas with the Canvas text API. It won't work without it. createImageData
is only useful for the reverse — generating an array of pixel data that you want drawn on a Canvas.
According to the docs, createImageBitmap
can be used to get the image data out of a <canvas>
or HTMLCanvasElement
as well. Shouldn't that be able to replace a canvasElem.getImageData()
call?
I believe after a bit of research that canvas fingerprinting is what's blocking sprites and glyphs. But there's also WebGL fingerprinting and blocking this causes the entire map to render as a white screen. That's why we see a difference between Chrome using the CanvasFingerprintBlock plugin and Brave. When you disable all fingerprinting in Brave, it blocks both Canvas and WebGL fingerprinting.
Under Technical Details, Brave says:
Because most browser fingerprinting defense requires disabling web features that are required for many sites to work properly, it is implemented as off-by-default for now (can be turned on in about:preferences globally, or on a per-site basis in the Bravery panel). We will consider turning it on-by-default when we have fingerprinting detection heuristics with a sufficiently-low false positive rate.
You can create an ImageBitmap
from a canvas
element, but the ImageBitmap
instance only has height
and width
properties; it does not expose the image data the way that canvas.getImageData
does (which returns an instance of ImageData
).
@ryanhamley does this mean that there are no next actions for us here — we just wait for browsers to get better at not blocking essential features when turning on fingerprinting protection, and rely on users not turning it fully on until that time — right?
That's what my research is pointing towards @mourner I want to do a bit more testing today before I close this though.
I did some fairly extensive research on this issue and there's not really anything we can do about it. Fingerprinting blockers disable functionality that GL JS relies on and there are no alternative ways of making the library work. This is a won't fix
issue.
In light of the unable to fix here I've opened https://github.com/mapbox/mapbox-gl-supported/issues/25 in case mapbox-gl-supported can detect the potential issue and return false.
The browser Brave's "device recognition"/"fingerprinting" blocking blocks anything that attempts to read data out of a canvas to prevent it from being used for browser fingerprinting (see https://browserleaks.com/canvas). This defaults to "block 3rd-party fingerprinting", which can apply when a map is embedded in an external website.
More on Google/Chrome's future plans for anti-fingerprinting functionality here.
mapbox-gl-js version: 1.0.0, any
browser: able to reproduce in Brave, Chrome given anti-fingerprinting settings enabled
Steps to Trigger Behavior
In Brave:
RangeError('out of range destination coordinates for image copy')
is thrown and no map is rendered: https://api.mapbox.com/styles/v1/mapbox/streets-v9.html?title=true&access_token=ACCESS_TOKEN#1.1/0/0 .In Chrome:
Link to Demonstration
https://jsbin.com/
Expected Behavior
The map is still rendered / icons are still rendered even when anti-fingerprinting settings are enabled.
Actual Behavior
In Brave with anti-fingerprinting, the map is not rendered. In Chrome with anti-fingerprinting, the icons from the spritesheet are not rendered.