Skip to content

Commit a98fe96

Browse files
authored
refactor: implement isStringBase64 and remove unmaintained dep (#414)
1 parent a5c8473 commit a98fe96

File tree

5 files changed

+89
-6
lines changed

5 files changed

+89
-6
lines changed

.changeset/huge-zoos-start.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@nodesecure/sec-literal": minor
3+
---
4+
5+
Remove un-maintained is-base64 package and re-implement the function in the sec-literal project with proper TS definition

workspaces/sec-literal/package.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@
3333
"homepage": "https://github.com/NodeSecure/js-x-ray/tree/master/workspaces/sec-literal#readme",
3434
"dependencies": {
3535
"frequency-set": "^2.1.0",
36-
"is-base64": "^1.1.0",
3736
"is-svg": "^6.0.0",
3837
"string-width": "^8.0.0"
39-
},
40-
"devDependencies": {
41-
"@types/is-base64": "^1.1.3"
4238
}
4339
}

workspaces/sec-literal/src/literal.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Import Third-party Dependencies
2-
import isStringBase64 from "is-base64";
1+
// Import Internal Dependencies
2+
import { isStringBase64 } from "./utils.js";
33

44
export type ESTreeLiteral = {
55
type: "Literal";

workspaces/sec-literal/src/utils.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,38 @@ import stringWidth from "string-width";
55
// Import Internal Dependencies
66
import { toValue, type ESTreeLiteral } from "./literal.js";
77

8+
export interface IsBase64Options {
9+
allowMime?: boolean;
10+
mimeRequired?: boolean;
11+
paddingRequired?: boolean;
12+
allowEmpty?: boolean;
13+
}
14+
15+
export function isStringBase64(
16+
v: string,
17+
opts: IsBase64Options = {}
18+
): boolean {
19+
if (opts.allowEmpty === false && v === "") {
20+
return false;
21+
}
22+
23+
let regex = "(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+\\/]{3}=)?";
24+
const mimeRegex = "(data:\\w+\\/[a-zA-Z\\+\\-\\.]+;base64,)";
25+
26+
if (opts.mimeRequired === true) {
27+
regex = mimeRegex + regex;
28+
}
29+
else if (opts.allowMime === true) {
30+
regex = mimeRegex + "?" + regex;
31+
}
32+
33+
if (opts.paddingRequired === false) {
34+
regex = "(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}(==)?|[A-Za-z0-9+\\/]{3}=?)?";
35+
}
36+
37+
return (new RegExp("^" + regex + "$", "gi")).test(v);
38+
}
39+
840
export function isSvg(
941
strOrLiteral: ESTreeLiteral | string
1042
): boolean {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* eslint-disable @stylistic/max-len */
2+
// Import Node.js Dependencies
3+
import { test } from "node:test";
4+
import assert from "node:assert/strict";
5+
6+
// Import Internal Dependencies
7+
import { isStringBase64 } from "../src/utils.js";
8+
9+
test("isBase64", function isBase64() {
10+
const pngString = "iVBORw0KGgoAAAANSUhEUgAABQAAAALQAQMAAAD1s08VAAAAA1BMVEX/AAAZ4gk3AAAAh0lEQVR42u3BMQEAAADCoPVPbQlPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4GsTfAAGc95RKAAAAAElFTkSuQmCC";
11+
const pngStringWithMime = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQAQMAAAD1s08VAAAAA1BMVEX/AAAZ4gk3AAAAh0lEQVR42u3BMQEAAADCoPVPbQlPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4GsTfAAGc95RKAAAAAElFTkSuQmCC";
12+
const jpgString = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEACAhITMkM1EwMFFCLy8vQiccHBwcJyIXFxcXFyIRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBIjMzNCY0IhgYIhQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDP/AABEIAAYABgMBIgACEQEDEQH/xABVAAEBAAAAAAAAAAAAAAAAAAAAAxAAAQQCAwEAAAAAAAAAAAAAAgABAxQEIxIkMxMBAQAAAAAAAAAAAAAAAAAAAAARAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AIE7MwkbOUJDJWx+ZjXATitx2/h2bEWvX5Y0npQ7aIiD/9k=";
13+
const jpgStringWithMime = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEACAhITMkM1EwMFFCLy8vQiccHBwcJyIXFxcXFyIRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBIjMzNCY0IhgYIhQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDP/AABEIAAYABgMBIgACEQEDEQH/xABVAAEBAAAAAAAAAAAAAAAAAAAAAxAAAQQCAwEAAAAAAAAAAAAAAgABAxQEIxIkMxMBAQAAAAAAAAAAAAAAAAAAAAARAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AIE7MwkbOUJDJWx+ZjXATitx2/h2bEWvX5Y0npQ7aIiD/9k=";
14+
15+
// Test agains real images
16+
assert.equal(isStringBase64(pngString), true);
17+
assert.equal(isStringBase64(pngStringWithMime), false);
18+
assert.equal(isStringBase64(pngStringWithMime, { allowMime: true }), true);
19+
assert.equal(isStringBase64(pngString, { mimeRequired: true }), false);
20+
assert.equal(isStringBase64(pngStringWithMime, { mimeRequired: true }), true);
21+
assert.equal(isStringBase64(jpgString), true);
22+
assert.equal(isStringBase64(jpgStringWithMime), false);
23+
assert.equal(isStringBase64(jpgStringWithMime, { allowMime: true }), true);
24+
25+
// helper for creating fake valid mime strings
26+
function createMimeString(mime: string): string {
27+
return `data:${mime};base64,${pngString}`;
28+
}
29+
30+
// Random complex mime types taken from:
31+
// http://www.freeformatter.com/mime-types-list.html
32+
assert.equal(isStringBase64(createMimeString("application/vnd.apple.installer+xml"), { allowMime: true }), true);
33+
assert.equal(isStringBase64(createMimeString("image/svg+xml"), { allowMime: true }), true);
34+
assert.equal(isStringBase64(createMimeString("application/set-payment-initiation"), { allowMime: true }), true);
35+
assert.equal(isStringBase64(createMimeString("image/vnd.adobe.photoshop"), { allowMime: true }), true);
36+
37+
assert.equal(isStringBase64("1342234"), false);
38+
assert.equal(isStringBase64("afQ$%rfew"), false);
39+
assert.equal(isStringBase64("dfasdfr342"), false);
40+
assert.equal(isStringBase64("uuLMhh"), false);
41+
assert.equal(isStringBase64("uuLMhh", { paddingRequired: false }), true);
42+
assert.equal(isStringBase64("uuLMhh", { paddingRequired: true }), false);
43+
assert.equal(isStringBase64("uuLMhh=="), true);
44+
assert.equal(isStringBase64("uuLMhh==", { paddingRequired: false }), true);
45+
assert.equal(isStringBase64("uuLMhh==", { paddingRequired: true }), true);
46+
assert.equal(isStringBase64("data:image/png;base64,uuLMhh==", { paddingRequired: true }), false);
47+
assert.equal(isStringBase64("data:image/png;base64,uuLMhh==", { paddingRequired: true, allowMime: true }), true);
48+
assert.equal(isStringBase64(""), true);
49+
assert.equal(isStringBase64("", { allowEmpty: false }), false);
50+
});

0 commit comments

Comments
 (0)