Skip to content

Commit

Permalink
Fix potential race-condition between getVersion() and connect() (qzin…
Browse files Browse the repository at this point in the history
…d#681)

Version before cert to avoid races
Co-authored-by: Berenz <[email protected]>
  • Loading branch information
tresf authored Jul 1, 2020
1 parent 63d76e1 commit 68d5d2d
Showing 1 changed file with 50 additions and 45 deletions.
95 changes: 50 additions & 45 deletions js/qz-tray.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

/**
* @version 2.1.1
* @version 2.1.1+1
* @overview QZ Tray Connector
* <p/>
* Connects a web client to the QZ Tray software.
Expand Down Expand Up @@ -38,7 +38,7 @@ var qz = (function() {
///// PRIVATE METHODS /////

var _qz = {
VERSION: "2.1.1", //must match @version above
VERSION: "2.1.1+1", //must match @version above
DEBUG: false,

log: {
Expand Down Expand Up @@ -342,32 +342,35 @@ var qz = (function() {
//also gives the user a chance to deny the connection
function sendCert(cert) {
if (cert === undefined) { cert = null; }
_qz.websocket.connection.sendData({ certificate: cert, promise: openPromise });
}

_qz.security.callCert().then(sendCert).catch(sendCert);
//websocket setup, query what version is connected
qz.api.getVersion().then(function(version) {
_qz.websocket.connection.version = version;
_qz.websocket.connection.semver = version.toLowerCase().replace(/-rc\./g, "-rc").split(/[\\+\\.-]/g);
for(var i = 0; i < _qz.websocket.connection.semver.length; i++) {
try {
if (i == 3 && _qz.websocket.connection.semver[i].toLowerCase().indexOf("rc") == 0) {
// Handle "rc1" pre-release by negating build info
_qz.websocket.connection.semver[i] = -(_qz.websocket.connection.semver[i].replace(/\D/g, ""));
continue;
}
_qz.websocket.connection.semver[i] = parseInt(_qz.websocket.connection.semver[i]);
}
catch(ignore) {}

//websocket setup, query what version is connected
qz.api.getVersion().then(function(version) {
_qz.websocket.connection.version = version;
_qz.websocket.connection.semver = version.toLowerCase().replace(/-rc\./g, "-rc").split(/[\\+\\.-]/g);
for(var i = 0; i < _qz.websocket.connection.semver.length; i++) {
try {
if (i == 3 && _qz.websocket.connection.semver[i].toLowerCase().indexOf("rc") == 0) {
// Handle "rc1" pre-release by negating build info
_qz.websocket.connection.semver[i] = -(_qz.websocket.connection.semver[i].replace(/\D/g, ""));
continue;
if (_qz.websocket.connection.semver.length < 4) {
_qz.websocket.connection.semver[3] = 0;
}
_qz.websocket.connection.semver[i] = parseInt(_qz.websocket.connection.semver[i]);
} catch(ignore) {}
if (_qz.websocket.connection.semver.length < 4) {
_qz.websocket.connection.semver[3] = 0;
}
}

//algorithm can be declared before a connection, check for incompatibilities now that we have one
_qz.compatible.algorithm(true);
});
//algorithm can be declared before a connection, check for incompatibilities now that we have one
_qz.compatible.algorithm(true);
}).then(function() {
_qz.websocket.connection.sendData({ certificate: cert, promise: openPromise });
});
}

_qz.security.callCert().then(sendCert).catch(sendCert);
},

/** Generate unique ID used to map a response to a call. */
Expand Down Expand Up @@ -570,9 +573,9 @@ var qz = (function() {
/** Create a new promise */
promise: function(resolver) {
//prefer global object for historical purposes
if(typeof RSVP !== 'undefined') {
if (typeof RSVP !== 'undefined') {
return new RSVP.Promise(resolver);
} else if(typeof Promise !== 'undefined') {
} else if (typeof Promise !== 'undefined') {
return new Promise(resolver);
} else {
_qz.log.error("Promise/A+ support is required. See qz.api.setPromiseType(...)");
Expand All @@ -595,7 +598,7 @@ var qz = (function() {

hash: function(data) {
//prefer global object for historical purposes
if(typeof Sha256 !== 'undefined') {
if (typeof Sha256 !== 'undefined') {
return Sha256.hash(data);
} else {
return _qz.SHA.hash(data);
Expand All @@ -609,7 +612,7 @@ var qz = (function() {
var a = document.createElement("a");
a.href = loc;
return a.href;
} else if(typeof exports === 'object') {
} else if (typeof exports === 'object') {
//node.js
require('path').resolve(loc);
}
Expand Down Expand Up @@ -801,7 +804,7 @@ var qz = (function() {
//if not connected yet we will assume compatibility exists for the time being
if (_qz.tools.isActive()) {
if (_qz.tools.isVersion(2, 0)) {
if(!quiet) {
if (!quiet) {
_qz.log.warn("Connected to an older version of QZ, alternate signature algorithms are not supported");
}
return false;
Expand Down Expand Up @@ -1202,7 +1205,9 @@ var qz = (function() {
* @memberof qz.printers
*/
startListening: function(printers) {
if (!Array.isArray(printers)) printers = [printers];
if (!Array.isArray(printers)) {
printers = [printers];
}
var params = {
printerNames: printers
};
Expand Down Expand Up @@ -2230,7 +2235,7 @@ var qz = (function() {
*/
device: function(hostname, port) {
// Wrap 2.0
if(_qz.tools.isVersion(2, 0)) {
if (_qz.tools.isVersion(2, 0)) {
return _qz.compatible.networking(hostname, port, null, null, function(data) {
return { ip: data.ipAddress, mac: data.macAddress };
});
Expand All @@ -2252,7 +2257,7 @@ var qz = (function() {
*/
devices: function(hostname, port) {
// Wrap 2.0
if(_qz.tools.isVersion(2, 0)) {
if (_qz.tools.isVersion(2, 0)) {
return _qz.compatible.networking(hostname, port, null, null, function(data) {
return [{ ip: data.ipAddress, mac: data.macAddress }];
});
Expand Down Expand Up @@ -2305,13 +2310,13 @@ var qz = (function() {
},

/**
* Set which signing algorithm QZ will check signatures against.
*
* @param {string} algorithm The algorithm used in signing. Valid values: <code>[SHA1 | SHA256 | SHA512]</code>
* @since 2.1.0
*
* @memberof qz.security
*/
* Set which signing algorithm QZ will check signatures against.
*
* @param {string} algorithm The algorithm used in signing. Valid values: <code>[SHA1 | SHA256 | SHA512]</code>
* @since 2.1.0
*
* @memberof qz.security
*/
setSignatureAlgorithm: function(algorithm) {
//warn for incompatibilities if known
if (!_qz.compatible.algorithm()) {
Expand All @@ -2326,13 +2331,13 @@ var qz = (function() {
},

/**
* Get the signing algorithm QZ will be checking signatures against.
*
* @returns {string} The algorithm used in signing.
* @since 2.1.0
*
* @memberof qz.security
*/
* Get the signing algorithm QZ will be checking signatures against.
*
* @returns {string} The algorithm used in signing.
* @since 2.1.0
*
* @memberof qz.security
*/
getSignatureAlgorithm: function() {
return _qz.security.signAlgorithm;
}
Expand Down

0 comments on commit 68d5d2d

Please sign in to comment.