From c10531b26269f314b01c81c54b22db9160df081c Mon Sep 17 00:00:00 2001 From: develar Date: Fri, 23 Dec 2016 09:03:55 +0100 Subject: [PATCH] fix: sha2 checksum error is not catchable Closes #1010 --- nsis-auto-updater/package.json | 2 +- nsis-auto-updater/src/electronHttpExecutor.ts | 26 +++++--------- package.json | 3 +- src/util/httpExecutor.ts | 15 ++++++++ src/util/nodeHttpExecutor.ts | 13 ++----- test/lint.js | 2 ++ yarn.lock | 35 ++++++++----------- 7 files changed, 46 insertions(+), 50 deletions(-) diff --git a/nsis-auto-updater/package.json b/nsis-auto-updater/package.json index 58fa22451d8..791616f0f56 100644 --- a/nsis-auto-updater/package.json +++ b/nsis-auto-updater/package.json @@ -1,6 +1,6 @@ { "name": "electron-auto-updater", - "version": "0.7.2", + "version": "0.8.2", "description": "NSIS Auto Updater", "main": "out/nsis-auto-updater/src/main.js", "author": "Vladimir Krivosheev", diff --git a/nsis-auto-updater/src/electronHttpExecutor.ts b/nsis-auto-updater/src/electronHttpExecutor.ts index d4a44a8593d..795dfdab119 100644 --- a/nsis-auto-updater/src/electronHttpExecutor.ts +++ b/nsis-auto-updater/src/electronHttpExecutor.ts @@ -3,13 +3,17 @@ import { net } from "electron" import { createWriteStream, ensureDir } from "fs-extra-p" import BluebirdPromise from "bluebird-lst-c" import * as path from "path" -import { HttpExecutor, DownloadOptions, HttpError, DigestTransform } from "../../src/util/httpExecutor" +import { HttpExecutor, DownloadOptions, HttpError, DigestTransform, checkSha2 } from "../../src/util/httpExecutor" import { Url } from "url" import { safeLoad } from "js-yaml" import _debug from "debug" import Debugger = debug.Debugger import { parse as parseUrl } from "url" +function safeGetHeader(response: Electron.IncomingMessage, headerKey: string) { + return response.headers[headerKey] ? response.headers[headerKey].pop() : null +} + export class ElectronHttpExecutor implements HttpExecutor { private readonly debug: Debugger = _debug("electron-builder") @@ -80,7 +84,7 @@ export class ElectronHttpExecutor implements HttpExecutor { return } - const redirectUrl = this.safeGetHeader(response, "location") + const redirectUrl = safeGetHeader(response, "location") if (redirectUrl != null) { if (redirectCount < this.maxRedirects) { this.doDownload(redirectUrl, destination, redirectCount++, options, callback) @@ -91,15 +95,8 @@ export class ElectronHttpExecutor implements HttpExecutor { return } - const sha2Header = this.safeGetHeader(response, "X-Checksum-Sha2") - if (sha2Header != null && options.sha2 != null) { - // todo why bintray doesn't send this header always - if (sha2Header == null) { - throw new Error("checksum is required, but server response doesn't contain X-Checksum-Sha2 header") - } - else if (sha2Header !== options.sha2) { - throw new Error(`checksum mismatch: expected ${options.sha2} but got ${sha2Header} (X-Checksum-Sha2 header)`) - } + if (!checkSha2(safeGetHeader(response, "X-Checksum-Sha2"), options.sha2, callback)) { + return } ensureDirPromise @@ -123,11 +120,6 @@ export class ElectronHttpExecutor implements HttpExecutor { request.end() } - private safeGetHeader(response: Electron.IncomingMessage, headerKey: string) { - return response.headers[headerKey] ? response.headers[headerKey].pop() : null - } - - doApiRequest(options: Electron.RequestOptions, token: string | null, requestProcessor: (request: Electron.ClientRequest, reject: (error: Error) => void) => void, redirectCount: number = 0): Promise { const requestOptions: any = options this.debug(`HTTPS request: ${JSON.stringify(requestOptions, null, 2)}`) @@ -153,7 +145,7 @@ Please double check that your authentication token is correct. Due to security r return } - const redirectUrl = this.safeGetHeader(response, "location") + const redirectUrl = safeGetHeader(response, "location") if (redirectUrl != null) { if (redirectCount > 10) { reject(new Error("Too many redirects (> 10)")) diff --git a/package.json b/package.json index 77932296275..379fc5c2bae 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "fs-extra-p": "^3.0.3", "hosted-git-info": "^2.1.5", "ini": "^1.3.4", + "interactive": "^0.1.9", "is-ci": "^1.0.10", "isbinaryfile": "^3.0.1", "js-yaml": "^3.7.0", @@ -114,7 +115,7 @@ "jest-environment-node-debug": "^0.0.2", "path-sort": "^0.1.0", "ts-babel": "^1.2.2", - "tslint": "^4.1.1", + "tslint": "^4.2.0", "typescript": "^2.1.4", "whitespace": "^2.1.0" }, diff --git a/src/util/httpExecutor.ts b/src/util/httpExecutor.ts index 08a4013f207..6de34d5e43e 100644 --- a/src/util/httpExecutor.ts +++ b/src/util/httpExecutor.ts @@ -60,4 +60,19 @@ export function githubRequest(path: string, token: string | null, data: {[nam export function request(url: Url, token: string | null = null, data: {[name: string]: any; } | null = null, method: string = "GET"): Promise { return executorHolder.httpExecutor.request(url, token, data, method) +} + +export function checkSha2(sha2Header: string | null | undefined, sha2: string | null | undefined, callback: (error: Error | null) => void): boolean { + if (sha2Header != null && sha2 != null) { + // todo why bintray doesn't send this header always + if (sha2Header == null) { + callback(new Error("checksum is required, but server response doesn't contain X-Checksum-Sha2 header")) + return false + } + else if (sha2Header !== sha2) { + callback(new Error(`checksum mismatch: expected ${sha2} but got ${sha2Header} (X-Checksum-Sha2 header)`)) + return false + } + } + return true } \ No newline at end of file diff --git a/src/util/nodeHttpExecutor.ts b/src/util/nodeHttpExecutor.ts index 287887a6650..21991bc7ec1 100644 --- a/src/util/nodeHttpExecutor.ts +++ b/src/util/nodeHttpExecutor.ts @@ -6,7 +6,7 @@ import BluebirdPromise from "bluebird-lst-c" import * as path from "path" import { homedir } from "os" import { parse as parseIni } from "ini" -import { HttpExecutor, DownloadOptions, HttpError, DigestTransform } from "./httpExecutor" +import { HttpExecutor, DownloadOptions, HttpError, DigestTransform, checkSha2 } from "./httpExecutor" import { Url } from "url" import { RequestOptions } from "https" import { safeLoad } from "js-yaml" @@ -91,15 +91,8 @@ export class NodeHttpExecutor implements HttpExecutor { return } - const sha2Header = response.headers["X-Checksum-Sha2"] - if (sha2Header != null && options.sha2 != null) { - // todo why bintray doesn't send this header always - if (sha2Header == null) { - throw new Error("checksum is required, but server response doesn't contain X-Checksum-Sha2 header") - } - else if (sha2Header !== options.sha2) { - throw new Error(`checksum mismatch: expected ${options.sha2} but got ${sha2Header} (X-Checksum-Sha2 header)`) - } + if (!checkSha2(response.headers["X-Checksum-Sha2"], options.sha2, callback)) { + return } ensureDirPromise diff --git a/test/lint.js b/test/lint.js index 2598eeed24d..2c48b966f60 100644 --- a/test/lint.js +++ b/test/lint.js @@ -59,6 +59,8 @@ const configuration = { "jsdoc-format": false, "no-for-in-array": true, "prefer-const": true, + "interface-over-type-literal": true, + "no-string-throw": true, } } const options = { diff --git a/yarn.lock b/yarn.lock index 44127e92201..ca693f7dac6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -543,10 +543,10 @@ binary@^0.3.0: chainsaw "~0.1.0" bl@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" + version "1.2.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.0.tgz#1397e7ec42c5f5dc387470c500e34a9f6be9ea98" dependencies: - readable-stream "~2.0.5" + readable-stream "^2.0.5" bluebird-lst-c@^1.0.5: version "1.0.5" @@ -555,8 +555,8 @@ bluebird-lst-c@^1.0.5: bluebird "^3.4.6" bluebird@^3.4.6: - version "3.4.6" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" + version "3.4.7" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" boom@2.x.x: version "2.10.1" @@ -1665,6 +1665,10 @@ ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" +interactive@^0.1.9: + version "0.1.9" + resolved "https://registry.yarnpkg.com/interactive/-/interactive-0.1.9.tgz#6dd3e2f9a00341863bc7dd84afce9d191b6f9e8e" + invariant@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" @@ -2968,17 +2972,6 @@ readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2. string_decoder "~0.10.x" util-deprecate "~1.0.1" -readable-stream@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - readdir-scoped-modules@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" @@ -3192,8 +3185,8 @@ sntp@1.x.x: hoek "2.x.x" source-map-support@^0.4.2, source-map-support@^0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.6.tgz#32552aa64b458392a85eab3b0b5ee61527167aeb" + version "0.4.7" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.7.tgz#7a7988e0e66241c778c78dd179199bb6bcd35bd6" dependencies: source-map "^0.5.3" @@ -3455,9 +3448,9 @@ ts-babel@^1.2.2: markdown-it "^8.2.0" source-map-support "^0.4.6" -tslint@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-4.1.1.tgz#ae15c9478d92eb2f01d5102c69c493ec02d7e7e4" +tslint@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-4.2.0.tgz#b9f5c5b871b784ab2f4809e704ade42d62f523ad" dependencies: babel-code-frame "^6.20.0" colors "^1.1.2"