js: Making objects inmutable
-- * An Object.freeze should stop any malicious third party from changing objects' methods once the objects are instantiated (see unittest for an approach that would have worked before) - An initialized gpgmejs- object doesn't have a '_Keyring' property anymore (it still has its 'Keyring') - The internal expect='base64' needed to be turned into a method.
This commit is contained in:
parent
522121ea7e
commit
e16a87e839
@ -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');
|
||||
|
@ -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(
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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':
|
||||
|
@ -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) {
|
||||
|
@ -66,7 +66,7 @@ export function createSignature(sigObject){
|
||||
}
|
||||
}
|
||||
}
|
||||
return new GPGME_Signature(sigObject);
|
||||
return Object.freeze(new GPGME_Signature(sigObject));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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'));
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user