
There are dozens of links in the OpenPGP.js codebase that are http but could be replaced with https links. I've converted as many of them as i could find.
232 lines
5.5 KiB
JavaScript
232 lines
5.5 KiB
JavaScript
/**
|
|
* This class represents a list of openpgp packets.
|
|
* Take care when iterating over it - the packets themselves
|
|
* are stored as numerical indices.
|
|
* @requires util
|
|
* @requires enums
|
|
* @requires packet
|
|
* @requires packet/packet
|
|
* @module packet/packetlist
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
import util from '../util';
|
|
import packetParser from './packet.js';
|
|
import * as packets from './all_packets.js';
|
|
import enums from '../enums.js';
|
|
import config from '../config';
|
|
|
|
/**
|
|
* @constructor
|
|
*/
|
|
export default function Packetlist() {
|
|
/** The number of packets contained within the list.
|
|
* @readonly
|
|
* @type {Integer} */
|
|
this.length = 0;
|
|
}
|
|
/**
|
|
* Reads a stream of binary data and interprents it as a list of packets.
|
|
* @param {Uint8Array} A Uint8Array of bytes.
|
|
*/
|
|
Packetlist.prototype.read = function (bytes) {
|
|
var i = 0;
|
|
|
|
while (i < bytes.length) {
|
|
var parsed = packetParser.read(bytes, i, bytes.length - i);
|
|
i = parsed.offset;
|
|
|
|
var pushed = false;
|
|
try {
|
|
var tag = enums.read(enums.packet, parsed.tag);
|
|
var packet = packets.newPacketFromTag(tag);
|
|
this.push(packet);
|
|
pushed = true;
|
|
packet.read(parsed.packet);
|
|
} catch(e) {
|
|
if (!config.tolerant || parsed.tag == enums.packet.symmetricallyEncrypted || parsed.tag == enums.packet.literal || parsed.tag == enums.packet.compressed) {
|
|
throw e;
|
|
}
|
|
if (pushed) {
|
|
this.pop(); // drop unsupported packet
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Creates a binary representation of openpgp objects contained within the
|
|
* class instance.
|
|
* @returns {Uint8Array} A Uint8Array containing valid openpgp packets.
|
|
*/
|
|
Packetlist.prototype.write = function () {
|
|
var arr = [];
|
|
|
|
for (var i = 0; i < this.length; i++) {
|
|
var packetbytes = this[i].write();
|
|
arr.push(packetParser.writeHeader(this[i].tag, packetbytes.length));
|
|
arr.push(packetbytes);
|
|
}
|
|
|
|
return util.concatUint8Array(arr);
|
|
};
|
|
|
|
/**
|
|
* Adds a packet to the list. This is the only supported method of doing so;
|
|
* writing to packetlist[i] directly will result in an error.
|
|
*/
|
|
Packetlist.prototype.push = function (packet) {
|
|
if (!packet) {
|
|
return;
|
|
}
|
|
|
|
packet.packets = packet.packets || new Packetlist();
|
|
|
|
this[this.length] = packet;
|
|
this.length++;
|
|
};
|
|
|
|
/**
|
|
* Remove a packet from the list and return it.
|
|
* @return {Object} The packet that was removed
|
|
*/
|
|
Packetlist.prototype.pop = function() {
|
|
if (this.length === 0) {
|
|
return;
|
|
}
|
|
|
|
var packet = this[this.length - 1];
|
|
delete this[this.length - 1];
|
|
this.length--;
|
|
|
|
return packet;
|
|
};
|
|
|
|
/**
|
|
* Creates a new PacketList with all packets that pass the test implemented by the provided function.
|
|
*/
|
|
Packetlist.prototype.filter = function (callback) {
|
|
|
|
var filtered = new Packetlist();
|
|
|
|
for (var i = 0; i < this.length; i++) {
|
|
if (callback(this[i], i, this)) {
|
|
filtered.push(this[i]);
|
|
}
|
|
}
|
|
|
|
return filtered;
|
|
};
|
|
|
|
/**
|
|
* Creates a new PacketList with all packets from the given types
|
|
*/
|
|
Packetlist.prototype.filterByTag = function () {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
var filtered = new Packetlist();
|
|
var that = this;
|
|
|
|
function handle(packetType) {return that[i].tag === packetType;}
|
|
for (var i = 0; i < this.length; i++) {
|
|
if (args.some(handle)) {
|
|
filtered.push(this[i]);
|
|
}
|
|
}
|
|
|
|
return filtered;
|
|
};
|
|
|
|
/**
|
|
* Executes the provided callback once for each element
|
|
*/
|
|
Packetlist.prototype.forEach = function (callback) {
|
|
for (var i = 0; i < this.length; i++) {
|
|
callback(this[i]);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Traverses packet tree and returns first matching packet
|
|
* @param {module:enums.packet} type The packet type
|
|
* @return {module:packet/packet|null}
|
|
*/
|
|
Packetlist.prototype.findPacket = function (type) {
|
|
var packetlist = this.filterByTag(type);
|
|
if (packetlist.length) {
|
|
return packetlist[0];
|
|
} else {
|
|
var found = null;
|
|
for (var i = 0; i < this.length; i++) {
|
|
if (this[i].packets.length) {
|
|
found = this[i].packets.findPacket(type);
|
|
if (found) {
|
|
return found;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
/**
|
|
* Returns array of found indices by tag
|
|
*/
|
|
Packetlist.prototype.indexOfTag = function () {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
var tagIndex = [];
|
|
var that = this;
|
|
|
|
function handle(packetType) {return that[i].tag === packetType;}
|
|
for (var i = 0; i < this.length; i++) {
|
|
if (args.some(handle)) {
|
|
tagIndex.push(i);
|
|
}
|
|
}
|
|
return tagIndex;
|
|
};
|
|
|
|
/**
|
|
* Returns slice of packetlist
|
|
*/
|
|
Packetlist.prototype.slice = function (begin, end) {
|
|
if (!end) {
|
|
end = this.length;
|
|
}
|
|
var part = new Packetlist();
|
|
for (var i = begin; i < end; i++) {
|
|
part.push(this[i]);
|
|
}
|
|
return part;
|
|
};
|
|
|
|
/**
|
|
* Concatenates packetlist or array of packets
|
|
*/
|
|
Packetlist.prototype.concat = function (packetlist) {
|
|
if (packetlist) {
|
|
for (var i = 0; i < packetlist.length; i++) {
|
|
this.push(packetlist[i]);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Allocate a new packetlist from structured packetlist clone
|
|
* See {@link https://w3c.github.io/html/infrastructure.html#safe-passing-of-structured-data}
|
|
* @param {Object} packetClone packetlist clone
|
|
* @returns {Object} new packetlist object with data from packetlist clone
|
|
*/
|
|
Packetlist.fromStructuredClone = function(packetlistClone) {
|
|
var packetlist = new Packetlist();
|
|
for (var i = 0; i < packetlistClone.length; i++) {
|
|
packetlist.push(packets.fromStructuredClone(packetlistClone[i]));
|
|
if (packetlist[i].packets.length !== 0) {
|
|
packetlist[i].packets = this.fromStructuredClone(packetlist[i].packets);
|
|
} else {
|
|
packetlist[i].packets = new Packetlist();
|
|
}
|
|
}
|
|
return packetlist;
|
|
};
|