MAPI
MAPI copied to clipboard
`Undefined array key` error in PropertyStore.php
Getting an error in hfig/mapi/src/MAPI/Property/PropertyStore.php on line 155.

A simple fix for now is to add a try/catch to the parseNameId function, and just skip any iterations of the foreach (str_split($propsData, 8) as $idx => $rawProp) loop that are throwing that error.
From a real use case scenario, I would much rather that any that are broken are just ignored and skipped, but the function still processes the message rather than ignoring it.
php - 8.0
hfip/mapi - 1.2.0
The code in Ruby looks like this:
props = props_obj.read.scan(/.{8}/mn).map do |str|
flags, offset = str[4..-1].unpack 'v2'
# the property will be serialised as this pseudo property, mapping it to this named property
pseudo_prop = 0x8000 + offset
named = flags & 1 == 1
prop = if named
str_off = str.unpack('V').first
len = names_data[str_off, 4].unpack('V').first
Ole::Types::FROM_UTF16.iconv names_data[str_off + 4, len]
else
a, b = str.unpack('v2')
Log.debug "b not 0" if b != 0
a
end
# a bit sus
guid_off = flags >> 1
# missing a few builtin PS_*
Log.debug "guid off < 2 (#{guid_off})" if guid_off < 2
guid = guids[guid_off - 2]
[pseudo_prop, Key.new(prop, guid)]
end
It was translated into PHP as
foreach (str_split($propsData, 8) as $idx => $rawProp) {
if (strlen($rawProp) < 8) break;
$d = unpack('vflags/voffset', substr($rawProp, 4));
$flags = $d['flags'];
$offset = $d['offset'];
//# the property will be serialised as this pseudo property, mapping it to this named property
$pseudo_prop = 0x8000 + $offset;
$named = ($flags & 1 == 1);
$prop = '';
if ($named) {
$str_off = unpack('V', $rawProp)[1];
if (strlen($namesData) - $str_off < 4) continue; // not sure with this, but at least it will not read outside the bounds and crash
$len = unpack('V', substr($namesData, $str_off, 4))[1];
$data = substr($namesData, $str_off + 4, $len);
$prop = mb_convert_encoding($data, 'UTF-8', 'UTF-16LE');
}
else {
$d = unpack('va/vb', $rawProp);
if ($d['b'] != 0) {
$this->logger->Debug("b not 0");
}
$prop = $d['a'];
}
//# a bit sus
$guid_off = $flags >> 1;
$guid = $guids[$guid_off - 2];
/*$properties[] = [
'key' => new PropertyKey($prop, $guid),
'prop' => $pseudo_prop,
];*/
$properties[$pseudo_prop] = new PropertyKey($prop, $guid);
}
Please check my translation.
Also check the spec https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxmsg/193c169b-0628-4392-aa51-83009be7d71f
(I believe what looks like an off-by-one issue in the decoding of the "Index and Kind Information" spec 2.2.3.1.2.1 [called "flags" and "offset" in the code] because of an indexing difference between the spec and the code.)
You apparently have with an offset of 3118 which means you have a file asking for the 1559th GUID property in the file. This is very - even absurdly - high. Suggests an invalid file. Can you provide the file?
In any case, I'd suggest:
- Verify the code is parsing the file as per the standard
- If so, make a PR to check
array_key_exists($guids, $guid_off-2)and, if the array key doesn't exist, skip adding it while logging a warning
Don't submit a PR with try {} catch {} of the whole routine, I'm not going to merge that!
Hi,
I have the same problem in case of trying to manage a outlook message with attachment:
/vendor/hfig/mapi/src/MAPI/Property/PropertyStore.php
"Undefined offset: 3116" line:155
/vendor/hfig/mapi/src/MAPI/Property/PropertyStore.php(155): yii\base\ErrorHandler->handleError()
vendor/hfig/mapi/src/MAPI/Property/PropertyStore.php(52): Hfig\MAPI\Property\PropertyStore->parseNameId()
/vendor/hfig/mapi/src/MAPI/Property/PropertyStore.php(41): Hfig\MAPI\Property\PropertyStore->load()
/vendor/hfig/mapi/src/MAPI/Message/Message.php(54): Hfig\MAPI\Property\PropertyStore->__construct()
/vendor/hfig/mapi/src/MAPI/MapiMessageFactory.php(22): Hfig\MAPI\Message\Message->__construct()
Hfig\MAPI\MapiMessageFactory->parseMessage()
Is there any solution how to fix this?
HI guys,
Does anyone find a solution for this problem by now? :-/