Skip to content

Commit

Permalink
plugins: prevent runtime errors when canvas context is null (setFillS…
Browse files Browse the repository at this point in the history
…tyles, setFonts) (#2299)

* Prevent accessing canvas attributes on null values in timeline and spectrogram plugins

* Guard remaining getContext calls

* Add to Changelog

* Fix variable scope error
  • Loading branch information
felguerez committed Jun 14, 2021
1 parent 5289c4e commit ccb7cf7
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 72 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ x.x.x (unreleased)
------------------
- Markers plugin: add the ability to use custom HTML elements in place of the default marker icon by passing the new `markerElement` parameter to the marker constructor (#2269)
- Regions plugin: handle rollover cursor bug fix (#2293)
- Timeline plugin: prevent calling Canvas context methods on null values (#2299)
- Spectrogram plugin: prevent calling Canvas context methods on null values (#2299)
- Markers plugin: trigger `marker-click` event on wavesurfer (#2287)

5.0.1 (05.05.2021)
Expand Down
126 changes: 65 additions & 61 deletions src/plugin/spectrogram/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,30 +254,32 @@ export default class SpectrogramPlugin {
const width = my.width;
const pixels = my.resample(frequenciesData);
const heightFactor = my.buffer ? 2 / my.buffer.numberOfChannels : 1;
const imageData = spectrCc.createImageData(width, height);
let i;
let j;
let k;

for (i = 0; i < pixels.length; i++) {
for (j = 0; j < pixels[i].length; j++) {
const colorMap = my.colorMap[pixels[i][j]];
/* eslint-disable max-depth */
for (k = 0; k < heightFactor; k++) {
let y = height - j * heightFactor;
if (heightFactor === 2 && k === 1) {
y--;
if (spectrCc) {
const imageData = spectrCc.createImageData(width, height);
let i;
let j;
let k;

for (i = 0; i < pixels.length; i++) {
for (j = 0; j < pixels[i].length; j++) {
const colorMap = my.colorMap[pixels[i][j]];
/* eslint-disable max-depth */
for (k = 0; k < heightFactor; k++) {
let y = height - j * heightFactor;
if (heightFactor === 2 && k === 1) {
y--;
}
const redIndex = y * (width * 4) + i * 4;
imageData.data[redIndex] = colorMap[0] * 255;
imageData.data[redIndex + 1] = colorMap[1] * 255;
imageData.data[redIndex + 2] = colorMap[2] * 255;
imageData.data[redIndex + 3] = colorMap[3] * 255;
}
const redIndex = y * (width * 4) + i * 4;
imageData.data[redIndex] = colorMap[0] * 255;
imageData.data[redIndex + 1] = colorMap[1] * 255;
imageData.data[redIndex + 2] = colorMap[2] * 255;
imageData.data[redIndex + 3] = colorMap[3] * 255;
/* eslint-enable max-depth */
}
/* eslint-enable max-depth */
}
spectrCc.putImageData(imageData, 0, 0);
}
spectrCc.putImageData(imageData, 0, 0);
}

getFrequencies(callback) {
Expand Down Expand Up @@ -378,47 +380,49 @@ export default class SpectrogramPlugin {
this.labelsEl.height = this.height;
this.labelsEl.width = bgWidth;

// fill background
ctx.fillStyle = bgFill;
ctx.fillRect(0, 0, bgWidth, getMaxY);
ctx.fill();
let i;

// render labels
for (i = 0; i <= labelIndex; i++) {
ctx.textAlign = textAlign;
ctx.textBaseline = 'middle';

const freq = freqStart + step * i;
const index = Math.round(
(freq / (this.sampleRate / 2)) * this.fftSamples
);
const label = this.freqType(freq);
const units = this.unitType(freq);
const yLabelOffset = 2;
const x = 16;
let y;

if (i == 0) {
y = getMaxY + i - 10;
// unit label
ctx.fillStyle = textColorUnit;
ctx.font = fontSizeUnit + ' ' + fontType;
ctx.fillText(units, x + 24, y);
// freq label
ctx.fillStyle = textColorFreq;
ctx.font = fontSizeFreq + ' ' + fontType;
ctx.fillText(label, x, y);
} else {
y = getMaxY - i * 50 + yLabelOffset;
// unit label
ctx.fillStyle = textColorUnit;
ctx.font = fontSizeUnit + ' ' + fontType;
ctx.fillText(units, x + 24, y);
// freq label
ctx.fillStyle = textColorFreq;
ctx.font = fontSizeFreq + ' ' + fontType;
ctx.fillText(label, x, y);
if (ctx) {
// fill background
ctx.fillStyle = bgFill;
ctx.fillRect(0, 0, bgWidth, getMaxY);
ctx.fill();
let i;

// render labels
for (i = 0; i <= labelIndex; i++) {
ctx.textAlign = textAlign;
ctx.textBaseline = 'middle';

const freq = freqStart + step * i;
const index = Math.round(
(freq / (this.sampleRate / 2)) * this.fftSamples
);
const label = this.freqType(freq);
const units = this.unitType(freq);
const yLabelOffset = 2;
const x = 16;
let y;

if (i == 0) {
y = getMaxY + i - 10;
// unit label
ctx.fillStyle = textColorUnit;
ctx.font = fontSizeUnit + ' ' + fontType;
ctx.fillText(units, x + 24, y);
// freq label
ctx.fillStyle = textColorFreq;
ctx.font = fontSizeFreq + ' ' + fontType;
ctx.fillText(label, x, y);
} else {
y = getMaxY - i * 50 + yLabelOffset;
// unit label
ctx.fillStyle = textColorUnit;
ctx.font = fontSizeUnit + ' ' + fontType;
ctx.fillText(units, x + 24, y);
// freq label
ctx.fillStyle = textColorFreq;
ctx.font = fontSizeFreq + ' ' + fontType;
ctx.fillText(label, x, y);
}
}
}
}
Expand Down
31 changes: 20 additions & 11 deletions src/plugin/timeline/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,10 @@ export default class TimelinePlugin {
*/
setFillStyles(fillStyle) {
this.canvases.forEach(canvas => {
canvas.getContext('2d').fillStyle = fillStyle;
const context = canvas.getContext('2d');
if (context) {
context.fillStyle = fillStyle;
}
});
}

Expand All @@ -445,7 +448,10 @@ export default class TimelinePlugin {
*/
setFonts(font) {
this.canvases.forEach(canvas => {
canvas.getContext('2d').font = font;
const context = canvas.getContext('2d');
if (context) {
context.font = font;
}
});
}

Expand All @@ -471,14 +477,17 @@ export default class TimelinePlugin {
};

if (intersection.x1 < intersection.x2) {
canvas
.getContext('2d')
.fillRect(
intersection.x1 - leftOffset,
intersection.y1,
intersection.x2 - intersection.x1,
intersection.y2 - intersection.y1
);
const context = canvas
.getContext('2d');
if (context) {
context
.fillRect(
intersection.x1 - leftOffset,
intersection.y1,
intersection.x2 - intersection.x1,
intersection.y2 - intersection.y1
);
}
}
});
}
Expand All @@ -502,7 +511,7 @@ export default class TimelinePlugin {
return;
}

if (xOffset + canvasWidth > x) {
if (xOffset + canvasWidth > x && context) {
textWidth = context.measureText(text).width;
context.fillText(text, x - xOffset, y);
}
Expand Down

0 comments on commit ccb7cf7

Please sign in to comment.