diff --git a/lang/js/BrowserTestExtension/tests/startup.js b/lang/js/BrowserTestExtension/tests/startup.js index 1e2784d9..63358aa9 100644 --- a/lang/js/BrowserTestExtension/tests/startup.js +++ b/lang/js/BrowserTestExtension/tests/startup.js @@ -37,7 +37,6 @@ describe('GPGME context', function(){ context.Keyring = input; expect(context.Keyring).to.be.an('object'); expect(context.Keyring).to.not.equal(input); - expect(context._Keyring).to.equal(context.Keyring); expect(context.Keyring.getKeys).to.be.a('function'); expect(context.Keyring.getDefaultKey).to.be.a('function'); expect(context.Keyring.importKey).to.be.a('function'); diff --git a/lang/js/src/Connection.js b/lang/js/src/Connection.js index 561a5b70..b0105757 100644 --- a/lang/js/src/Connection.js +++ b/lang/js/src/Connection.js @@ -118,7 +118,7 @@ export class Connection{ } let chunksize = message.chunksize; return new Promise(function(resolve, reject){ - let answer = new Answer(message); + let answer = Object.freeze(new Answer(message)); let listener = function(msg) { if (!msg){ _connection.onMessage.removeListener(listener); @@ -188,14 +188,15 @@ class Answer{ */ constructor(message){ const operation = message.operation; - const expect = message.expect; + const expected = message.getExpect(); let response_b64 = null; this.getOperation = function(){ return operation; }; + this.getExpect = function(){ - return expect; + return expected; }; /** @@ -260,7 +261,7 @@ class Answer{ } if (_decodedResponse.base64 === true && poa.data[key] === 'string' - && this.getExpect() === undefined + && this.getExpect() !== 'base64' ){ _response[key] = decodeURIComponent( atob(_decodedResponse[key]).split('').map( diff --git a/lang/js/src/Errors.js b/lang/js/src/Errors.js index 0cf1af19..39e3a74a 100644 --- a/lang/js/src/Errors.js +++ b/lang/js/src/Errors.js @@ -119,7 +119,7 @@ const err_list = { export function gpgme_error(code = 'GENERIC_ERROR', info){ if (err_list.hasOwnProperty(code)){ if (err_list[code].type === 'error'){ - return new GPGME_Error(code); + return Object.freeze(new GPGME_Error(code)); } if (err_list[code].type === 'warning'){ // eslint-disable-next-line no-console @@ -127,10 +127,10 @@ export function gpgme_error(code = 'GENERIC_ERROR', info){ } return null; } else if (code === 'GNUPG_ERROR'){ - return new GPGME_Error(code, info); + return Object.freeze(new GPGME_Error(code, info)); } else { - return new GPGME_Error('GENERIC_ERROR'); + return Object.freeze(new GPGME_Error('GENERIC_ERROR')); } } diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js index d5873a70..f431a283 100644 --- a/lang/js/src/Key.js +++ b/lang/js/src/Key.js @@ -37,7 +37,7 @@ export function createKey(fingerprint, async = false){ if (!isFingerprint(fingerprint) || typeof(async) !== 'boolean'){ return gpgme_error('PARAM_WRONG'); } - else return new GPGME_Key(fingerprint, async); + else return Object.freeze(new GPGME_Key(fingerprint, async)); } /** @@ -104,15 +104,15 @@ export class GPGME_Key { case 'subkeys': _data.subkeys = []; for (let i=0; i< data.subkeys.length; i++) { - _data.subkeys.push( - new GPGME_Subkey(data.subkeys[i])); + _data.subkeys.push(Object.freeze( + new GPGME_Subkey(data.subkeys[i]))); } break; case 'userids': _data.userids = []; for (let i=0; i< data.userids.length; i++) { - _data.userids.push( - new GPGME_UserId(data.userids[i])); + _data.userids.push(Object.freeze( + new GPGME_UserId(data.userids[i]))); } break; case 'last_update': diff --git a/lang/js/src/Message.js b/lang/js/src/Message.js index c0b6ed57..e2c07344 100644 --- a/lang/js/src/Message.js +++ b/lang/js/src/Message.js @@ -36,7 +36,7 @@ export function createMessage(operation){ return gpgme_error('PARAM_WRONG'); } if (permittedOperations.hasOwnProperty(operation)){ - return new GPGME_Message(operation); + return Object.freeze(new GPGME_Message(operation)); } else { return gpgme_error('MSG_WRONG_OP'); } @@ -56,11 +56,21 @@ export class GPGME_Message { op: operation, chunksize: 1023* 1024 }; + let expected = null; this.getOperation = function(){ return _msg.op; }; + this.setExpect = function(value){ + if (value === 'base64'){ + expected = value; + } + }; + this.getExpect = function(){ + return expected; + }; + /** * The maximum size of responses from gpgme in bytes. As of July 2018, * most browsers will only accept answers up to 1 MB of size. @@ -204,7 +214,7 @@ export class GPGME_Message { return new Promise(function(resolve, reject) { if (me.isComplete() === true) { - let conn = new Connection; + let conn = Object.freeze(new Connection); conn.post(me).then(function(response) { resolve(response); }, function(reason) { diff --git a/lang/js/src/Signature.js b/lang/js/src/Signature.js index 0ee58e94..55131b01 100644 --- a/lang/js/src/Signature.js +++ b/lang/js/src/Signature.js @@ -66,7 +66,7 @@ export function createSignature(sigObject){ } } } - return new GPGME_Signature(sigObject); + return Object.freeze(new GPGME_Signature(sigObject)); } diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js index 720490d6..9154979d 100644 --- a/lang/js/src/gpgmejs.js +++ b/lang/js/src/gpgmejs.js @@ -102,7 +102,7 @@ export class GpgME { */ this.getKeyring = function(){ if (!_Keyring){ - _Keyring = new GPGME_Keyring; + _Keyring = Object.freeze(new GPGME_Keyring); } return _Keyring; }; @@ -241,7 +241,7 @@ export class GpgME { putData(msg, data); return new Promise(function(resolve,reject) { if (mode ==='detached'){ - msg.expect= 'base64'; + msg.setExpect('base64'); } msg.post().then( function(message) { if (mode === 'clearsign'){ @@ -319,10 +319,7 @@ export class GpgME { * Accesses the {@link GPGME_Keyring}. */ get Keyring(){ - if (!this._Keyring){ - this._Keyring = new GPGME_Keyring; - } - return this._Keyring; + return this.getKeyring(); } } diff --git a/lang/js/src/index.js b/lang/js/src/index.js index dc613fc7..2fed95f9 100644 --- a/lang/js/src/index.js +++ b/lang/js/src/index.js @@ -34,11 +34,11 @@ import { Connection } from './Connection'; */ function init(){ return new Promise(function(resolve, reject){ - let connection = new Connection; + let connection = Object.freeze(new Connection); connection.checkConnection(false).then( function(result){ if (result === true) { - resolve(new GpgME()); + resolve(Object.freeze(new GpgME())); } else { reject(gpgme_error('CONN_NO_CONNECT')); } diff --git a/lang/js/unittests.js b/lang/js/unittests.js index 6228993b..3304b1eb 100644 --- a/lang/js/unittests.js +++ b/lang/js/unittests.js @@ -253,6 +253,22 @@ function unittests (){ expect(key.fingerprint.code).to.equal('KEY_INVALID'); } }); + + it('Overwriting getFingerprint does not work', function(){ + const evilFunction = function(){ + return 'bad Data'; + }; + let key = createKey(kp.validKeyFingerprint, true); + expect(key.fingerprint).to.equal(kp.validKeyFingerprint); + try { + key.getFingerprint = evilFunction; + } + catch(e) { + expect(e).to.be.an.instanceof(TypeError); + } + expect(key.fingerprint).to.equal(kp.validKeyFingerprint); + expect(key.getFingerprint).to.not.equal(evilFunction); + }); // TODO: tests for subkeys // TODO: tests for userids // TODO: some invalid tests for key/keyring