New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@kenjiuno/msgreader

Package Overview
Dependencies
Maintainers
1
Versions
87
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kenjiuno/msgreader - npm Package Compare versions

Comparing version 1.6.6 to 1.7.0

lib/EntryStreamParser.d.ts

9

cli.js

@@ -170,2 +170,11 @@ const program = require('commander');

program
.command('dummy2')
.action(() => {
const msgFileBuffer = fs.readFileSync('test/voteItems.msg');
const testMsg = new MsgReader(msgFileBuffer);
const testMsgInfo = testMsg.getFileData();
console.log(testMsgInfo);
});
program
.parse(process.argv);

@@ -61,2 +61,3 @@ declare const _default: {

'7ffe': string;
'0c15': string;
'3001': string;

@@ -67,2 +68,12 @@ '3002': string;

};
PIDLID_MAPPING: {
"00062008-0000-0000-c000-000000000046": {
34080: {
id: string;
};
34084: {
id: string;
};
};
};
CLASS_MAPPING: {

@@ -75,2 +86,4 @@ ATTACHMENT_DATA: string;

'0102': string;
'0003': string;
'000b': string;
};

@@ -77,0 +90,0 @@ DIR_TYPE: {

15

lib/const.js

@@ -76,2 +76,3 @@ "use strict";

// recipient specific
'0c15': 'recipType',
'3001': 'name',

@@ -82,2 +83,12 @@ '3002': 'addressType',

},
PIDLID_MAPPING: {
"00062008-0000-0000-c000-000000000046": {
0x00008520: {
id: "PidLidVerbStream"
},
0x00008524: {
id: "PidLidVerbResponse"
}
}
},
CLASS_MAPPING: {

@@ -89,3 +100,5 @@ ATTACHMENT_DATA: '3701'

'001f': 'unicode',
'0102': 'binary'
'0102': 'binary',
'0003': 'integer',
'000b': 'boolean'
},

@@ -92,0 +105,0 @@ DIR_TYPE: {

@@ -371,2 +371,11 @@ export interface ParserConfig {

}
declare enum KeyType {
root = 0,
toSub = 1
}
interface FieldValuePair {
key: string;
keyType: KeyType;
value: string | Uint8Array;
}
/**

@@ -380,5 +389,10 @@ * The core implementation of MsgReader

private innerMsgBurners;
/**
* pidTag: 0x8000 ~ 0xFFFF
*/
private privatePidToKeyed;
constructor(arrayBuffer: ArrayBuffer | DataView);
private getFieldValue;
private decodeField;
private fieldsDataDocument;
setDecodedFieldTo(fields: FieldsData, pair: FieldValuePair): void;
private getFieldType;

@@ -391,2 +405,3 @@ private fieldsDataDirInner;

private fieldsDataDir;
private fieldsNameIdDir;
/**

@@ -411,1 +426,2 @@ * extract real fields

}
export {};

248

lib/MsgReader.js

@@ -18,2 +18,6 @@ "use strict";

var _EntryStreamParser = require("./EntryStreamParser");
var _VerbStreamParser = require("./VerbStreamParser");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

@@ -53,2 +57,9 @@

var KeyType;
(function (KeyType) {
KeyType[KeyType["root"] = 0] = "root";
KeyType[KeyType["toSub"] = 1] = "toSub";
})(KeyType || (KeyType = {}));
function fileTimeToUnixEpoch(time) {

@@ -63,2 +74,5 @@ return (time - 116444736000000000) / 10000;

var MsgReader = /*#__PURE__*/function () {
/**
* pidTag: 0x8000 ~ 0xFFFF
*/
function MsgReader(arrayBuffer) {

@@ -75,2 +89,4 @@ _classCallCheck(this, MsgReader);

_defineProperty(this, "privatePidToKeyed", void 0);
this.reader = new _Reader.Reader(arrayBuffer);

@@ -80,15 +96,79 @@ }

_createClass(MsgReader, [{
key: "getFieldValue",
value: function getFieldValue(fieldProperty, type) {
var array = fieldProperty.provider();
key: "decodeField",
value: function decodeField(fieldClass, fieldType, provider, insideProps) {
var array = provider();
var ds = new _DataStream["default"](array, 0, _DataStream["default"].LITTLE_ENDIAN);
var decodeAs = _const["default"].MSG.FIELD.TYPE_MAPPING[type];
var key = _const["default"].MSG.FIELD.NAME_MAPPING[fieldClass];
var keyType = KeyType.root;
var classValue = parseInt("0x".concat(fieldClass));
if (0) {} else if (decodeAs === "string") {
return ds.readString(fieldProperty.length);
if (classValue >= 0x8000) {
var keyed = this.privatePidToKeyed[classValue];
if (keyed) {
if (keyed.useName) {
key = keyed.name;
keyType = KeyType.toSub;
} else {
var lidDict = _const["default"].MSG.FIELD.PIDLID_MAPPING[keyed.propertySet];
if (lidDict !== undefined) {
var prop = lidDict[keyed.propertyLid];
if (prop !== undefined) {
key = prop.id;
keyType = KeyType.toSub;
}
}
}
}
}
var value = array;
var skip = false;
var decodeAs = _const["default"].MSG.FIELD.TYPE_MAPPING[fieldType];
if (0) {} else if (key === "PidLidVerbStream") {
value = (0, _VerbStreamParser.parse)(ds);
} else if (decodeAs === "string") {
value = ds.readString(array.length);
skip = insideProps;
} else if (decodeAs === "unicode") {
return ds.readUCS2String(fieldProperty.length / 2);
value = ds.readUCS2String(array.length / 2);
skip = insideProps;
} else if (decodeAs === "integer") {
value = ds.readUint32();
} else if (decodeAs === "boolean") {
value = ds.readUint16() ? true : false;
}
return array;
if (skip) {
key = undefined;
}
if (0) {} else if (key === "PidLidVerbResponse") {
key = "votingResponse";
keyType = KeyType.root;
} else if (key === "PidLidVerbStream") {
key = "votingOptions";
keyType = KeyType.root;
} else if (key === "recipType") {
var MAPI_TO = 1;
var MAPI_CC = 2;
var MAPI_BCC = 3;
if (0) {} else if (value === MAPI_TO) {
value = "to";
} else if (value === MAPI_CC) {
value = "cc";
} else if (value === MAPI_BCC) {
value = "bcc";
}
}
return {
key: key,
keyType: keyType,
value: value
};
}

@@ -102,8 +182,3 @@ }, {

parserConfig.propertyObserver && parserConfig.propertyObserver(fields, parseInt(value.substring(0, 8), 16), documentProperty.provider());
var fieldName = _const["default"].MSG.FIELD.NAME_MAPPING[fieldClass];
if (fieldName) {
fields[fieldName] = this.getFieldValue(documentProperty, fieldType);
}
if (fieldClass == _const["default"].MSG.FIELD.CLASS_MAPPING.ATTACHMENT_DATA) {

@@ -113,5 +188,20 @@ // attachment specific info

fields.contentLength = documentProperty.length;
} else {
this.setDecodedFieldTo(fields, this.decodeField(fieldClass, fieldType, documentProperty.provider, false));
}
}
}, {
key: "setDecodedFieldTo",
value: function setDecodedFieldTo(fields, pair) {
var key = pair.key,
keyType = pair.keyType,
value = pair.value;
if (key !== undefined) {
if (keyType === KeyType.root) {
fields[key] = value;
}
}
}
}, {
key: "getFieldType",

@@ -143,3 +233,3 @@ value: function getFieldType(fieldProperty) {

// unknown, read
this.fieldsDataDir(parserConfig, dirProperty, rootFolder, fields, "nameid");
this.fieldsNameIdDir(parserConfig, dirProperty, rootFolder, fields);
} else {

@@ -224,3 +314,3 @@ // other dir

var sources = rootFolder.subFolders().filter(function (it) {
return it.name === "__nameid_version1.0";
return it.name === _const["default"].MSG.FIELD.PREFIX.NAMEID;
});

@@ -276,2 +366,4 @@

value: function fieldsRecipAndAttachmentProperties(parserConfig, documentProperty, fields) {
var _this2 = this;
var propertiesBinary = documentProperty.provider();

@@ -281,46 +373,17 @@ var propertiesDs = new _DataStream["default"](propertiesBinary, 8, _DataStream["default"].LITTLE_ENDIAN); // See: [MS-OXMSG]: Outlook Item (.msg) File Format, 2.4 Property Stream

var PtypInteger32 = 0x0003;
var PtypBoolean = 0x000B;
var PidTagRecipientType = 0x0C150003;
while (!propertiesDs.isEof()) {
var _loop = function _loop() {
var propertyTag = propertiesDs.readUint32();
var flags = propertiesDs.readUint32();
var fieldClass = (0, _utils.toHexStr)(propertyTag >> 16 & 65535, 4);
var fieldType = (0, _utils.toHexStr)(propertyTag & 65535, 4);
var ptyp = propertyTag & 0xFFFF;
var value = undefined;
var rawDataPos = propertiesDs.position;
var fieldClass = (0, _utils.toHex2)(propertyTag >> 16 & 65535);
var fieldType = (0, _utils.toHex2)(propertyTag & 65535);
var raw = propertiesDs.readUint8Array(8);
parserConfig.propertyObserver(fields, propertyTag, raw);
if (ptyp === PtypInteger32) {
value = propertiesDs.readUint32();
} else if (ptyp === PtypBoolean) {
value = propertiesDs.readUint16() ? true : false;
}
_this2.setDecodedFieldTo(fields, _this2.decodeField(fieldClass, fieldType, function () {
return raw;
}, true));
};
propertiesDs.seek(rawDataPos);
var _raw = propertiesDs.readUint8Array(8);
parserConfig.propertyObserver(fields, propertyTag, _raw);
if (propertyTag === PidTagRecipientType) {
var MAPI_TO = 1;
var MAPI_CC = 2;
var MAPI_BCC = 3;
if (value === MAPI_TO) {
fields["recipType"] = "to";
} else if (value === MAPI_CC) {
fields["recipType"] = "cc";
} else if (value === MAPI_BCC) {
fields["recipType"] = "bcc";
}
} else {
var fieldName = _const["default"].MSG.FIELD.NAME_MAPPING[fieldClass]; //console.info("@", fieldClass, propertyTag, fieldName, value);
if (fieldName && value !== undefined) {
fields[fieldName] = value;
}
}
while (!propertiesDs.isEof()) {
_loop();
}

@@ -368,7 +431,2 @@ }

value: function fieldsDataDir(parserConfig, dirProperty, rootFolder, fields, subClass) {
if (subClass === "nameid") {
// skip normal processing
return;
}
var _iterator4 = _createForOfIteratorHelper(dirProperty.subFolders()),

@@ -411,2 +469,71 @@ _step4;

}
}, {
key: "fieldsNameIdDir",
value: function fieldsNameIdDir(parserConfig, dirProperty, rootFolder, fields) {
var guidTable = undefined;
var stringTable = undefined;
var entryTable = undefined;
var _iterator6 = _createForOfIteratorHelper(dirProperty.fileNameSets()),
_step6;
try {
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
var fileSet = _step6.value;
if (0) {} else if (fileSet.name.indexOf(_const["default"].MSG.FIELD.PREFIX.DOCUMENT) == 0) {
var value = fileSet.name.substring(12).toLowerCase();
var fieldClass = value.substring(0, 4);
var fieldType = value.substring(4, 8);
if (0) {} else if (fieldClass === "0002" && fieldType === "0102") {
guidTable = fileSet.provider();
} else if (fieldClass === "0003" && fieldType === "0102") {
entryTable = fileSet.provider();
} else if (fieldClass === "0004" && fieldType === "0102") {
stringTable = fileSet.provider();
}
}
} //console.log("%", guidTable, stringTable, entryTable);
} catch (err) {
_iterator6.e(err);
} finally {
_iterator6.f();
}
if (guidTable !== undefined && stringTable !== undefined && entryTable !== undefined) {
var entries = (0, _EntryStreamParser.parse)(entryTable);
var stringReader = new _DataStream["default"](stringTable, 0, _DataStream["default"].LITTLE_ENDIAN);
var _iterator7 = _createForOfIteratorHelper(entries),
_step7;
try {
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
var entry = _step7.value;
if (entry.isStringProperty) {
stringReader.seek(entry.key);
var numTextBytes = stringReader.readUint32();
this.privatePidToKeyed[0x8000 | entry.propertyIndex] = {
useName: true,
name: stringReader.readUCS2String(numTextBytes / 2)
};
} else {
this.privatePidToKeyed[0x8000 | entry.propertyIndex] = {
useName: false,
propertySet: entry.guidIndex === 1 ? "00020328-00000-0000-C000-00000000046" : entry.guidIndex === 2 ? "00020329-00000-0000-C000-00000000046" : (0, _utils.msftUuidStringify)(guidTable, 16 * (entry.guidIndex - 3)),
propertyLid: entry.key
};
}
} //console.log("@", this.privatePidToKeyed);
} catch (err) {
_iterator7.e(err);
} finally {
_iterator7.f();
}
}
}
/**

@@ -451,2 +578,3 @@ * extract real fields

this.innerMsgBurners = {};
this.privatePidToKeyed = {};
this.fieldsData = this.parseMsgData({

@@ -453,0 +581,0 @@ propertyObserver: ((_this$parserConfig = this.parserConfig) === null || _this$parserConfig === void 0 ? void 0 : _this$parserConfig.propertyObserver) || function () {}

@@ -13,1 +13,30 @@ /**

export declare function toHexStr(value: number, padding: number): string;
/**
* byte to hex string
*
* @internal
*/
export declare function toHex1(value: number): string;
/**
* little uint16 to hex string
*
* @internal
*/
export declare function toHex2(value: number): string;
/**
* little uint32 to hex string
*
* @internal
*/
export declare function toHex4(value: number): string;
/**
* Variant 2 UUIDs, historically used in Microsoft's COM/OLE libraries,
* use a mixed-endian format, whereby the first three components of the UUID are little-endian,
* and the last two are big-endian.
* For example, `00112233-4455-6677-8899-aabbccddeeff` is encoded as the bytes
* `33 22 11 00 55 44 77 66 88 99 aa bb cc dd ee ff`.
*
* @see https://en.wikipedia.org/wiki/Universally_unique_identifier
* @internal
*/
export declare function msftUuidStringify(array: ArrayLike<number>, offset: number): string;

@@ -9,2 +9,6 @@ "use strict";

exports.toHexStr = toHexStr;
exports.toHex1 = toHex1;
exports.toHex2 = toHex2;
exports.toHex4 = toHex4;
exports.msftUuidStringify = msftUuidStringify;

@@ -59,2 +63,48 @@ /**

return text;
}
var hex = "0123456789abcdef";
/**
* byte to hex string
*
* @internal
*/
function toHex1(value) {
return hex[value >> 4 & 15] + hex[value & 15];
}
/**
* little uint16 to hex string
*
* @internal
*/
function toHex2(value) {
return hex[value >> 12 & 15] + hex[value >> 8 & 15] + hex[value >> 4 & 15] + hex[value & 15];
}
/**
* little uint32 to hex string
*
* @internal
*/
function toHex4(value) {
return hex[value >> 28 & 15] + hex[value >> 24 & 15] + hex[value >> 20 & 15] + hex[value >> 16 & 15] + hex[value >> 12 & 15] + hex[value >> 8 & 15] + hex[value >> 4 & 15] + hex[value & 15];
}
/**
* Variant 2 UUIDs, historically used in Microsoft's COM/OLE libraries,
* use a mixed-endian format, whereby the first three components of the UUID are little-endian,
* and the last two are big-endian.
* For example, `00112233-4455-6677-8899-aabbccddeeff` is encoded as the bytes
* `33 22 11 00 55 44 77 66 88 99 aa bb cc dd ee ff`.
*
* @see https://en.wikipedia.org/wiki/Universally_unique_identifier
* @internal
*/
function msftUuidStringify(array, offset) {
return "" + toHex1(array[offset + 3]) + toHex1(array[offset + 2]) + toHex1(array[offset + 1]) + toHex1(array[offset + 0]) + "-" + toHex1(array[offset + 5]) + toHex1(array[offset + 4]) + "-" + toHex1(array[offset + 7]) + toHex1(array[offset + 6]) + "-" + toHex1(array[offset + 8]) + toHex1(array[offset + 9]) + "-" + toHex1(array[offset + 10]) + toHex1(array[offset + 11]) + toHex1(array[offset + 12]) + toHex1(array[offset + 13]) + toHex1(array[offset + 14]) + toHex1(array[offset + 15]);
}
{
"name": "@kenjiuno/msgreader",
"version": "1.6.6",
"version": "1.7.0",
"description": "",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc