Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String.match RangeError: Maximum call stack size exceeded

Can this line of code

someString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);

cause this issue: RangeError: Maximum call stack size exceeded by any means?

this is being called in a method, which is inside a loop to process n no. of images

function imageUpload(images) {
  for (index = 0; index < images.length; index++) {
    base64Data = images[index];
    imageBuffer = decodeBase64Image(base64Data);
  }
}

function decodeBase64Image(dataString) {
  matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
  response = {};
  if (matches.length !== 3) {
    return new Error('Invalid input string');
  }

  response.type = matches[1];
  response.data = new Buffer(matches[2], 'base64');
  return response;
}

Could this be global vars?

Note: I'm not able to reproduce this issue. We just caught this over sentry for production environment.

Thanks in advance.

like image 437
Abhishek Avatar asked Oct 15 '25 19:10

Abhishek


1 Answers

Yes, the regex can throw the mentioned error. I had the same regex just with more capturing groups (/^data:([A-Za-z]+)\/([A-Za-z-+0-9/]+);base64,(.+)$/).

While the regex works for smaller images or files, it does not work for bigger files. In my case, a JPEG image with the dimensions 4624x3468 and the size of 3.67 MB was too large.

Solution:

You can use basic string operations for everything you need:

export function extractBase64Data (src) {
  const idxComma = src.indexOf(",")
  const idxSlash = src.indexOf("/")

  if (idxComma === -1 || idxSlash === -1 || !src.startsWith("data:")) {
    throw new Error("Invalid data URL")
  }

  const idxSemi = src.indexOf(";");
  const extEnd = idxSemi === -1 
    ? idxComma 
    : Math.min(idxSemi, idxComma)

  return {
    type: src.substring("data:".length, idxSlash),
    extension: src.substring(idxSlash + 1, extEnd),
    data: src.substring(idxComma + 1).trim(),
  }
}

This function works for data URLs with or without an encoding scheme.

Keep in mind that there are better options than to send images/files in base64 to the backend, like FormData or Blobs/Bytes per sockets. But if you want to use base64, the above works.

like image 83
Ainias Avatar answered Oct 17 '25 09:10

Ainias