Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions lib/Parser/MimeDir.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
*/
class MimeDir extends Parser
{
public const TOKEN_PROPNAME = 1;
public const TOKEN_PROPVALUE = 2;
public const TOKEN_PARAMNAME = 3;
public const TOKEN_PARAMVALUE = 4;

/**
* The input stream.
*
Expand Down Expand Up @@ -362,6 +367,12 @@ protected function readProperty($line)
'value' => null,
];

/*
* Keep track on the last token we parsed in order to do
* better error checking
*/
$lastToken = null;

$lastParam = null;

/*
Expand All @@ -387,10 +398,16 @@ protected function readProperty($line)
// option is set to ignore invalid lines, we ignore this line
// This can happen when servers provide faulty data as iCloud
// frequently does with X-APPLE-STRUCTURED-LOCATION
$lastToken = self::TOKEN_PARAMVALUE;
continue;
}
throw new ParseException('Invalid Mimedir file. Line starting at '.$this->startLine.' did not follow iCalendar/vCard conventions');
}

if ('=' == $match[0][0] && self::TOKEN_PARAMNAME != $lastToken) {
throw new ParseException('Invalid Mimedir file. Line starting at '.$this->startLine.': Missing parameter name for parameter value "'.$match['paramValue'].'"');
}

if (is_null($property['parameters'][$lastParam])) {
$property['parameters'][$lastParam] = $value;
} elseif (is_array($property['parameters'][$lastParam])) {
Expand All @@ -404,21 +421,25 @@ protected function readProperty($line)
$value,
];
}
$lastToken = self::TOKEN_PARAMVALUE;
continue;
}
if (isset($match['paramName'])) {
$lastParam = strtoupper($match['paramName']);
if (!isset($property['parameters'][$lastParam])) {
$property['parameters'][$lastParam] = null;
}
$lastToken = self::TOKEN_PARAMNAME;
continue;
}
if (isset($match['propValue'])) {
$property['value'] = $match['propValue'];
$lastToken = self::TOKEN_PROPVALUE;
continue;
}
if (isset($match['name']) && 0 < strlen($match['name'])) {
$property['name'] = strtoupper($match['name']);
$lastToken = self::TOKEN_PROPNAME;
continue;
}

Expand Down
17 changes: 17 additions & 0 deletions tests/VObject/Parser/MimeDirTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,21 @@ public function testPropertyName0(): void
$vevent = $mimeDir->parse($iCal);
self::assertEquals('test', $vevent->VEVENT->{0}->getValue());
}

public function testInvalidParameter(): void
{
$this->expectException(ParseException::class);
$this->expectExceptionMessage('Invalid Mimedir file. Line starting at 3: Missing parameter name for parameter value "value2"');
$vcard = <<<EOF
BEGIN:VCARD
VERSION:4.0
FN;P1=value1; P2=value2:value
UID:1234
END:VCARD
EOF;
$mimeDir = new MimeDir();
$vcard = $mimeDir->parse($vcard);

echo $vcard->serialize();
}
}
Loading