Skip to content

Commit 4df5cdd

Browse files
authored
fix: accept BOM in package manifests
Closes openupm/openupm#4135
1 parent 6da4735 commit 4df5cdd

5 files changed

Lines changed: 63 additions & 10 deletions

File tree

createPackageArtifactMetadata.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const crypto = require("crypto");
22
const fs = require("fs");
33
const path = require("path");
4+
const { readPackageJson } = require("./lib/packageJson");
45

56
/**
67
* @param {string} filePath
@@ -31,7 +32,7 @@ const createPackageArtifactMetadata = function (
3132
distTag,
3233
) {
3334
const packageJsonPath = path.resolve(packageFolder, "package.json");
34-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
35+
const packageJson = readPackageJson(packageJsonPath);
3536
const resolvedTarballPath = path.resolve(tarballPath);
3637

3738
return {

findPackage.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,7 @@ const findit = require("findit2");
44
const path = require("path");
55
const relative = require("relative");
66
const { logDebug, logError } = require("./lib/logger");
7-
8-
/**
9-
* @param {string} filePath
10-
* @returns {{name?: string}}
11-
*/
12-
const readPackageJson = function (filePath) {
13-
const raw = fs.readFileSync(filePath, "utf8");
14-
return JSON.parse(raw);
15-
};
7+
const { readPackageJson } = require("./lib/packageJson");
168

179
/**
1810
* @param {string} packageName

lib/packageJson.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const fs = require("fs");
2+
3+
/**
4+
* @param {string} text
5+
* @returns {string}
6+
*/
7+
const stripLeadingBom = function (text) {
8+
return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
9+
};
10+
11+
/**
12+
* @param {string} text
13+
* @returns {{name?: string, version?: string}}
14+
*/
15+
const parsePackageJsonText = function (text) {
16+
return JSON.parse(stripLeadingBom(text));
17+
};
18+
19+
/**
20+
* @param {string} filePath
21+
* @returns {{name?: string, version?: string}}
22+
*/
23+
const readPackageJson = function (filePath) {
24+
return parsePackageJsonText(fs.readFileSync(filePath, "utf8"));
25+
};
26+
27+
module.exports = {
28+
parsePackageJsonText,
29+
readPackageJson,
30+
stripLeadingBom,
31+
};

test/test-createPackageArtifactMetadata.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,24 @@ describe("createPackageArtifactMetadata.js", function () {
5454
signed: false,
5555
});
5656
});
57+
58+
it("creates artifact metadata from package.json with a UTF-8 BOM", function () {
59+
const packageDir = path.join(tmpDir, "pkg");
60+
const tarballPath = path.join(packageDir, "package-a-1.0.0.tgz");
61+
fs.mkdirSync(packageDir, { recursive: true });
62+
fs.writeFileSync(
63+
path.join(packageDir, "package.json"),
64+
'\uFEFF{"name":"package-a","version":"1.0.0"}\n',
65+
);
66+
fs.writeFileSync(tarballPath, "tarball-content");
67+
68+
const metadata = createPackageArtifactMetadata(
69+
packageDir,
70+
tarballPath,
71+
"latest",
72+
);
73+
74+
metadata.packageName.should.equal("package-a");
75+
metadata.packageVersion.should.equal("1.0.0");
76+
});
5777
});

test/test-findPackage.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable no-undef */
22
require("should");
3+
const fs = require("fs");
34
const path = require("path");
45
const { spawnSync } = require("child_process");
56
const {
@@ -27,6 +28,14 @@ describe("findPackage.js", function () {
2728
const result = await findPackage("package-a", tmpDir);
2829
result.pkg.name.should.equal("package-a");
2930
});
31+
it("finds package.json with a UTF-8 BOM", async function () {
32+
const packageJsonPath = path.resolve(tmpDir, "package.json");
33+
fs.writeFileSync(packageJsonPath, '\uFEFF{"name":"package-a"}\n');
34+
35+
const result = await findPackage("package-a", tmpDir);
36+
37+
result.pkg.name.should.equal("package-a");
38+
});
3039
it("find failed", async function () {
3140
const result = await findPackage("package-a", tmpDir);
3241
(result == null).should.be.ok();

0 commit comments

Comments
 (0)