From 95e6f30a605466081b575317b4445f231c8f0b4e Mon Sep 17 00:00:00 2001 From: Tom Hu Date: Mon, 19 Apr 2021 21:18:52 -0400 Subject: [PATCH 1/3] Update validation regex and bump to 1.4.1 --- CHANGELOG.md | 4 ++++ dist/index.js | 2 +- package-lock.json | 2 +- package.json | 2 +- src/validate.ts | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32b18327a..182dc7890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.4.1 +## Fixes +- #287 Update VERSION regex to restrict on digits and dot + ## 1.4.0 ### Features - #282 Add checksum verification of bash script diff --git a/dist/index.js b/dist/index.js index ff84a32d3..1790159da 100644 --- a/dist/index.js +++ b/dist/index.js @@ -49280,7 +49280,7 @@ var calculateChecksum = function (body, i) { return shasum.digest('hex') + " codecov"; }; var getVersion = function (body) { - var regex = /VERSION="(.*)+"/g; + var regex = /VERSION="([\d\.]+)"/g; var match = regex.exec(body); return match ? match[1] : null; }; diff --git a/package-lock.json b/package-lock.json index 10ff0c1b4..b0958e6d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "codecov-action", - "version": "1.4.0", + "version": "1.4.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 2c6af5b9d..8d0dda65d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codecov-action", - "version": "1.4.0", + "version": "1.4.1", "description": "Upload coverage reports to Codecov from GitHub Actions", "main": "index.js", "scripts": { diff --git a/src/validate.ts b/src/validate.ts index 68cbd63ad..55b2e3a8a 100644 --- a/src/validate.ts +++ b/src/validate.ts @@ -50,7 +50,7 @@ const calculateChecksum = (body, i) => { }; const getVersion = (body) => { - const regex = /VERSION="(.*)+"/g; + const regex = /VERSION="([\d\.]+)"/g; const match = regex.exec(body); return match ? match[1] : null; }; From 50895b2a6fdcabba1eae4f13c5d67adbe85d7a90 Mon Sep 17 00:00:00 2001 From: Tom Hu Date: Tue, 20 Apr 2021 08:35:56 -0400 Subject: [PATCH 2/3] Pull checksums into script --- CHANGELOG.md | 2 +- dist/index.js | 215 ++++++++++++++++--------------------------- src/index.ts | 2 +- src/validate.test.ts | 21 ++++- src/validate.ts | 39 ++++---- 5 files changed, 116 insertions(+), 163 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 182dc7890..ae4873132 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## 1.4.1 ## Fixes -- #287 Update VERSION regex to restrict on digits and dot +- #287 Update VERSION regex to restrict on digits and dot and move checksums into script ## 1.4.0 ### Features diff --git a/dist/index.js b/dist/index.js index 1790159da..098358f16 100644 --- a/dist/index.js +++ b/dist/index.js @@ -13203,66 +13203,58 @@ try { timeout: 3000, url: 'https://codecov.io/bash', }, function (error, response, body) { return __awaiter(void 0, void 0, void 0, function () { - var _a, execArgs, options, filepath, failCi, isValid, failure, error_1; + var _a, execArgs, options, filepath, failCi, isValid, failure; return __generator(this, function (_b) { - switch (_b.label) { - case 0: - _a = buildExec_1["default"](), execArgs = _a.execArgs, options = _a.options, filepath = _a.filepath, failCi = _a.failCi; - _b.label = 1; - case 1: - _b.trys.push([1, 3, , 4]); - return [4 /*yield*/, validate_1["default"](body)]; - case 2: - isValid = _b.sent(); - if (!isValid) { - failure = 'Codecov failure: ' + - 'Bash script checksums do not match published values. ' + - 'Please contact security@codecov.io immediately.'; - core.setFailed(failure); - throw new Error(failure); - } - if (error && failCi) { - throw error; + _a = buildExec_1["default"](), execArgs = _a.execArgs, options = _a.options, filepath = _a.filepath, failCi = _a.failCi; + try { + isValid = validate_1["default"](body); + if (!isValid) { + failure = 'Codecov failure: ' + + 'Bash script checksums do not match published values. ' + + 'Please contact security@codecov.io immediately.'; + core.setFailed(failure); + throw new Error(failure); + } + if (error && failCi) { + throw error; + } + else if (error) { + core.warning("Codecov warning: " + error.message); + } + fs.writeFile(filepath, body, function (err) { + if (err && failCi) { + throw err; } - else if (error) { - core.warning("Codecov warning: " + error.message); + else if (err) { + core.warning("Codecov warning: " + err.message); } - fs.writeFile(filepath, body, function (err) { - if (err && failCi) { - throw err; + exec.exec('bash', execArgs, options)["catch"](function (err) { + if (failCi) { + core.setFailed("Codecov failed with the following error: " + err.message); } - else if (err) { + else { core.warning("Codecov warning: " + err.message); } - exec.exec('bash', execArgs, options)["catch"](function (err) { - if (failCi) { - core.setFailed("Codecov failed with the following error: " + err.message); + }) + .then(function () { + unlinkFile(); + }); + var unlinkFile = function () { + fs.unlink(filepath, function (err) { + if (err && failCi) { + throw err; } - else { + else if (err) { core.warning("Codecov warning: " + err.message); } - }) - .then(function () { - unlinkFile(); }); - var unlinkFile = function () { - fs.unlink(filepath, function (err) { - if (err && failCi) { - throw err; - } - else if (err) { - core.warning("Codecov warning: " + err.message); - } - }); - }; - }); - return [3 /*break*/, 4]; - case 3: - error_1 = _b.sent(); - core.setFailed("Codecov failed with the following error: " + error_1.message); - return [3 /*break*/, 4]; - case 4: return [2 /*return*/]; + }; + }); } + catch (error) { + core.setFailed("Codecov failed with the following error: " + error.message); + } + return [2 /*return*/]; }); }); }); } @@ -49178,106 +49170,53 @@ module.exports = function (data, opts) { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; exports.__esModule = true; exports.retrieveChecksum = void 0; var crypto = __webpack_require__(417); var core = __webpack_require__(470); var request = __webpack_require__(335); -var validateUploader = function (body) { return __awaiter(void 0, void 0, void 0, function () { - var version, _i, _a, i, publicChecksum, uploaderChecksum; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - version = getVersion(body); - if (version === null) { - core.warning('Codecov could not identify the bash uploader version.'); - return [2 /*return*/, false]; - } - _i = 0, _a = [1, 256, 512]; - _b.label = 1; - case 1: - if (!(_i < _a.length)) return [3 /*break*/, 4]; - i = _a[_i]; - return [4 /*yield*/, exports.retrieveChecksum(version, i)]; - case 2: - publicChecksum = _b.sent(); - uploaderChecksum = calculateChecksum(body, i); - if (uploaderChecksum !== publicChecksum.trim()) { - core.warning("Codecov " + version + " checksums for SHA" + i + " failed to match.\n" + - ("Public checksum: " + publicChecksum) + - ("Uploader checksum: " + uploaderChecksum)); - return [2 /*return*/, false]; - } - _b.label = 3; - case 3: - _i++; - return [3 /*break*/, 1]; - case 4: return [2 /*return*/, true]; +var validateUploader = function (body) { + var version = getVersion(body); + if (version === null) { + core.warning('Codecov could not identify the bash uploader version.'); + return false; + } + for (var _i = 0, _a = [1, 256, 512]; _i < _a.length; _i++) { + var i = _a[_i]; + var publicChecksum = exports.retrieveChecksum(version, i); + var uploaderChecksum = calculateChecksum(body, i); + if (uploaderChecksum !== publicChecksum) { + core.warning("Codecov " + version + " checksums for SHA" + i + " failed to match.\n" + + ("Public checksum: " + publicChecksum) + + ("Uploader checksum: " + uploaderChecksum)); + return false; } - }); -}); }; -var retrieveChecksum = function (version, encryption) { return __awaiter(void 0, void 0, void 0, function () { - var url, response; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - url = "https://raw.githubusercontent.com/codecov/codecov-bash/" + version + "/SHA" + encryption + "SUM"; - return [4 /*yield*/, request({ - maxAttempts: 10, - timeout: 3000, - url: url, - })]; - case 1: - response = _a.sent(); - if (response.statusCode != 200) { - core.warning("Codecov could not retrieve checksum SHA" + encryption + " at " + url); - return [2 /*return*/, '']; - } - return [2 /*return*/, response.body]; + } + return true; +}; +var retrieveChecksum = function (version, encryption) { + var checksums = { + '1.0.1': { + '1': '0ddc61a9408418c73b19a1375f63bb460dc947a8', + '256': '89c658e261d5f25533598a222fd96cf17a5fa0eb3772f2defac754d9970b2ec8', + '512': 'd075b412a362a9a2b7aedfec3b8b9a9a927b3b99e98c7c15a2b76ef09862aeb005e91d76a5fd71b511141496d0fd23d1b42095f722ebcd509d768fba030f159e', + }, + '1.0.2': { + '1': '537069158a6f72b145cfe5f782dceb608d9ef594', + '256': 'd6aa3207c4908d123bd8af62ec0538e3f2b9f257c3de62fad4e29cd3b59b41d9', + '512': 'b6492196dd844cd81a688536bb42463d28bd666448335c4a8fc7f8f9b9b9afc346a467e3401e3fc49e6047442a30d93a4adfaa1590101224a186013c6179c48d', } - }); -}); }; + }; + if (version in checksums && encryption in checksums[version]) { + return checksums[version][encryption]; + } + return null; +}; exports.retrieveChecksum = retrieveChecksum; var calculateChecksum = function (body, i) { var shasum = crypto.createHash("sha" + i); shasum.update(body); - return shasum.digest('hex') + " codecov"; + return "" + shasum.digest('hex'); }; var getVersion = function (body) { var regex = /VERSION="([\d\.]+)"/g; diff --git a/src/index.ts b/src/index.ts index 4cb77680c..ca8628854 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,7 +18,7 @@ try { const {execArgs, options, filepath, failCi} = buildExec(); try { - const isValid = await validateUploader(body); + const isValid = validateUploader(body); if (!isValid) { const failure = 'Codecov failure: ' + 'Bash script checksums do not match published values. ' + diff --git a/src/validate.test.ts b/src/validate.test.ts index f59c8384c..bbae55f40 100644 --- a/src/validate.test.ts +++ b/src/validate.test.ts @@ -17,23 +17,34 @@ const bashScript = (async () => { }); test('valid checksums', async () => { - const valid = await validateUploader(await bashScript()); + const valid = validateUploader(await bashScript()); expect(valid).toBeTruthy(); }); test('invalid checksums', async () => { const script = await bashScript(); - const valid = await validateUploader(script.substring(0, script.length - 1)); + const valid = validateUploader(script.substring(0, script.length - 1)); expect(valid).toBeFalsy(); }); test('invalid script version', async () => { const script = await bashScript(); - const valid = await validateUploader(script.substring(0, 20)); + const valid = validateUploader(script.substring(0, 20)); expect(valid).toBeFalsy(); }); -test('invalid public checksum file', async () => { - const checksum = await retrieveChecksum('foo', 'bar'); +test('invalid public checksum file', () => { + const checksum = retrieveChecksum('foo', 'bar'); expect(checksum).toBeFalsy(); }); + +test('invalid public checksum file', () => { + const checksum = retrieveChecksum('foo', 'bar'); + expect(checksum).toBeFalsy(); +}); + +test('invalid encryption', () => { + const checksum = retrieveChecksum('1.0.1', 'foo'); + expect(checksum).toBeFalsy(); +}); + diff --git a/src/validate.ts b/src/validate.ts index 55b2e3a8a..2bb154c2f 100644 --- a/src/validate.ts +++ b/src/validate.ts @@ -4,7 +4,7 @@ const core = require('@actions/core'); const request = require('requestretry'); -const validateUploader = async (body) => { +const validateUploader = (body) => { const version = getVersion(body); if (version === null) { core.warning('Codecov could not identify the bash uploader version.'); @@ -12,9 +12,9 @@ const validateUploader = async (body) => { } for (const i of [1, 256, 512]) { - const publicChecksum = await retrieveChecksum(version, i); + const publicChecksum = retrieveChecksum(version, i); const uploaderChecksum = calculateChecksum(body, i); - if (uploaderChecksum !== publicChecksum.trim()) { + if (uploaderChecksum !== publicChecksum) { core.warning( `Codecov ${version} checksums for SHA${i} failed to match.\n` + `Public checksum: ${publicChecksum}` + @@ -26,27 +26,30 @@ const validateUploader = async (body) => { return true; }; -export const retrieveChecksum = async (version, encryption) => { - const url = `https://raw.githubusercontent.com/codecov/codecov-bash/${version}/SHA${encryption}SUM`; - const response = await request({ - maxAttempts: 10, - timeout: 3000, - url: url, - }); - - if (response.statusCode != 200) { - core.warning( - `Codecov could not retrieve checksum SHA${encryption} at ${url}`, - ); - return ''; +export const retrieveChecksum = (version, encryption) => { + const checksums = { + '1.0.1': { + '1': '0ddc61a9408418c73b19a1375f63bb460dc947a8', + '256': '89c658e261d5f25533598a222fd96cf17a5fa0eb3772f2defac754d9970b2ec8', + '512': 'd075b412a362a9a2b7aedfec3b8b9a9a927b3b99e98c7c15a2b76ef09862aeb005e91d76a5fd71b511141496d0fd23d1b42095f722ebcd509d768fba030f159e', + }, + '1.0.2': { + '1': '537069158a6f72b145cfe5f782dceb608d9ef594', + '256': 'd6aa3207c4908d123bd8af62ec0538e3f2b9f257c3de62fad4e29cd3b59b41d9', + '512': 'b6492196dd844cd81a688536bb42463d28bd666448335c4a8fc7f8f9b9b9afc346a467e3401e3fc49e6047442a30d93a4adfaa1590101224a186013c6179c48d', + } + }; + + if (version in checksums && encryption in checksums[version]) { + return checksums[version][encryption]; } - return response.body; + return null; }; const calculateChecksum = (body, i) => { const shasum = crypto.createHash(`sha${i}`); shasum.update(body); - return `${shasum.digest('hex')} codecov`; + return `${shasum.digest('hex')}`; }; const getVersion = (body) => { From 77a7b61cd5a14d69c7be61baee31fa1690f6e891 Mon Sep 17 00:00:00 2001 From: Tom Hu Date: Tue, 20 Apr 2021 08:38:33 -0400 Subject: [PATCH 3/3] Lint --- dist/index.js | 9 +++++---- src/validate.ts | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/dist/index.js b/dist/index.js index 098358f16..fc6d4b4e1 100644 --- a/dist/index.js +++ b/dist/index.js @@ -49174,7 +49174,6 @@ exports.__esModule = true; exports.retrieveChecksum = void 0; var crypto = __webpack_require__(417); var core = __webpack_require__(470); -var request = __webpack_require__(335); var validateUploader = function (body) { var version = getVersion(body); if (version === null) { @@ -49199,13 +49198,15 @@ var retrieveChecksum = function (version, encryption) { '1.0.1': { '1': '0ddc61a9408418c73b19a1375f63bb460dc947a8', '256': '89c658e261d5f25533598a222fd96cf17a5fa0eb3772f2defac754d9970b2ec8', - '512': 'd075b412a362a9a2b7aedfec3b8b9a9a927b3b99e98c7c15a2b76ef09862aeb005e91d76a5fd71b511141496d0fd23d1b42095f722ebcd509d768fba030f159e', + '512': 'd075b412a362a9a2b7aedfec3b8b9a9a927b3b99e98c7c15a2b76ef09862ae' + + 'b005e91d76a5fd71b511141496d0fd23d1b42095f722ebcd509d768fba030f159e', }, '1.0.2': { '1': '537069158a6f72b145cfe5f782dceb608d9ef594', '256': 'd6aa3207c4908d123bd8af62ec0538e3f2b9f257c3de62fad4e29cd3b59b41d9', - '512': 'b6492196dd844cd81a688536bb42463d28bd666448335c4a8fc7f8f9b9b9afc346a467e3401e3fc49e6047442a30d93a4adfaa1590101224a186013c6179c48d', - } + '512': 'b6492196dd844cd81a688536bb42463d28bd666448335c4a8fc7f8f9b9b9af' + + 'c346a467e3401e3fc49e6047442a30d93a4adfaa1590101224a186013c6179c48d', + }, }; if (version in checksums && encryption in checksums[version]) { return checksums[version][encryption]; diff --git a/src/validate.ts b/src/validate.ts index 2bb154c2f..55baa2073 100644 --- a/src/validate.ts +++ b/src/validate.ts @@ -2,8 +2,6 @@ const crypto = require('crypto'); const core = require('@actions/core'); -const request = require('requestretry'); - const validateUploader = (body) => { const version = getVersion(body); if (version === null) { @@ -31,13 +29,15 @@ export const retrieveChecksum = (version, encryption) => { '1.0.1': { '1': '0ddc61a9408418c73b19a1375f63bb460dc947a8', '256': '89c658e261d5f25533598a222fd96cf17a5fa0eb3772f2defac754d9970b2ec8', - '512': 'd075b412a362a9a2b7aedfec3b8b9a9a927b3b99e98c7c15a2b76ef09862aeb005e91d76a5fd71b511141496d0fd23d1b42095f722ebcd509d768fba030f159e', + '512': 'd075b412a362a9a2b7aedfec3b8b9a9a927b3b99e98c7c15a2b76ef09862ae' + + 'b005e91d76a5fd71b511141496d0fd23d1b42095f722ebcd509d768fba030f159e', }, '1.0.2': { '1': '537069158a6f72b145cfe5f782dceb608d9ef594', '256': 'd6aa3207c4908d123bd8af62ec0538e3f2b9f257c3de62fad4e29cd3b59b41d9', - '512': 'b6492196dd844cd81a688536bb42463d28bd666448335c4a8fc7f8f9b9b9afc346a467e3401e3fc49e6047442a30d93a4adfaa1590101224a186013c6179c48d', - } + '512': 'b6492196dd844cd81a688536bb42463d28bd666448335c4a8fc7f8f9b9b9af' + + 'c346a467e3401e3fc49e6047442a30d93a4adfaa1590101224a186013c6179c48d', + }, }; if (version in checksums && encryption in checksums[version]) {