Skip to content

Commit 63f5dc8

Browse files
fix: check if properties exist before using them
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
1 parent ac3fe70 commit 63f5dc8

File tree

2 files changed

+984
-303
lines changed

2 files changed

+984
-303
lines changed

lib/private/Calendar/Manager.php

Lines changed: 95 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Sabre\VObject\Component\VCalendar;
3434
use Sabre\VObject\Component\VEvent;
3535
use Sabre\VObject\Component\VFreeBusy;
36+
use Sabre\VObject\ParseException;
3637
use Sabre\VObject\Property\VCard\DateTime;
3738
use Sabre\VObject\Reader;
3839
use Throwable;
@@ -235,9 +236,14 @@ public function handleIMipRequest(
235236
$this->logger->warning('iMip message could not be processed because user has no calendars');
236237
return false;
237238
}
238-
239-
/** @var VCalendar $vObject|null */
240-
$calendarObject = Reader::read($calendarData);
239+
240+
try {
241+
/** @var VCalendar $vObject|null */
242+
$calendarObject = Reader::read($calendarData);
243+
} catch (ParseException $e) {
244+
$this->logger->error('iMip message could not be processed because an error occurred while parsing the iMip message', ['exception' => $e]);
245+
return false;
246+
}
241247

242248
if (!isset($calendarObject->METHOD) || $calendarObject->METHOD->getValue() !== 'REQUEST') {
243249
$this->logger->warning('iMip message contains an incorrect or invalid method');
@@ -249,13 +255,19 @@ public function handleIMipRequest(
249255
return false;
250256
}
251257

258+
/** @var VEvent|null $vEvent */
252259
$eventObject = $calendarObject->VEVENT;
253260

254261
if (!isset($eventObject->UID)) {
255262
$this->logger->warning('iMip message event dose not contains a UID');
256263
return false;
257264
}
258265

266+
if (!isset($eventObject->ORGANIZER)) {
267+
$this->logger->warning('iMip message event dose not contains an organizer');
268+
return false;
269+
}
270+
259271
if (!isset($eventObject->ATTENDEE)) {
260272
$this->logger->warning('iMip message event dose not contains any attendees');
261273
return false;
@@ -296,7 +308,7 @@ public function handleIMipRequest(
296308
}
297309
}
298310

299-
$this->logger->warning('iMip message event could not be processed because the no corresponding event was found in any calendar');
311+
$this->logger->warning('iMip message event could not be processed because no corresponding event was found in any calendar');
300312
return false;
301313
}
302314

@@ -309,45 +321,67 @@ public function handleIMipReply(
309321
string $recipient,
310322
string $calendarData,
311323
): bool {
312-
/** @var VCalendar $vObject|null */
313-
$vObject = Reader::read($calendarData);
324+
325+
$calendars = $this->getCalendarsForPrincipal($principalUri);
326+
if (empty($calendars)) {
327+
$this->logger->warning('iMip message could not be processed because user has no calendars');
328+
return false;
329+
}
330+
331+
try {
332+
/** @var VCalendar $vObject|null */
333+
$vObject = Reader::read($calendarData);
334+
} catch (ParseException $e) {
335+
$this->logger->error('iMip message could not be processed because an error occurred while parsing the iMip message', ['exception' => $e]);
336+
return false;
337+
}
314338

315339
if ($vObject === null) {
340+
$this->logger->warning('iMip message contains an invalid calendar object');
341+
return false;
342+
}
343+
344+
if (!isset($vObject->METHOD) || $vObject->METHOD->getValue() !== 'REPLY') {
345+
$this->logger->warning('iMip message contains an incorrect or invalid method');
346+
return false;
347+
}
348+
349+
if (!isset($vObject->VEVENT)) {
350+
$this->logger->warning('iMip message contains no event');
316351
return false;
317352
}
318353

319354
/** @var VEvent|null $vEvent */
320-
$vEvent = $vObject->{'VEVENT'};
355+
$vEvent = $vObject->VEVENT;
356+
357+
if (!isset($vEvent->UID)) {
358+
$this->logger->warning('iMip message event dose not contains a UID');
359+
return false;
360+
}
321361

322-
if ($vEvent === null) {
362+
if (!isset($vEvent->ORGANIZER)) {
363+
$this->logger->warning('iMip message event dose not contains an organizer');
323364
return false;
324365
}
325366

326-
// First, we check if the correct method is passed to us
327-
if (strcasecmp('REPLY', $vObject->{'METHOD'}->getValue()) !== 0) {
328-
$this->logger->warning('Wrong method provided for processing');
367+
if (!isset($vEvent->ATTENDEE)) {
368+
$this->logger->warning('iMip message event dose not contains any attendees');
329369
return false;
330370
}
331371

332372
// check if mail recipient and organizer are one and the same
333373
$organizer = substr($vEvent->{'ORGANIZER'}->getValue(), 7);
334374

335375
if (strcasecmp($recipient, $organizer) !== 0) {
336-
$this->logger->warning('Recipient and ORGANIZER must be identical');
376+
$this->logger->warning('iMip message event could not be processed because recipient and ORGANIZER must be identical');
337377
return false;
338378
}
339379

340380
//check if the event is in the future
341381
/** @var DateTime $eventTime */
342382
$eventTime = $vEvent->{'DTSTART'};
343383
if ($eventTime->getDateTime()->getTimeStamp() < $this->timeFactory->getTime()) { // this might cause issues with recurrences
344-
$this->logger->warning('Only events in the future are processed');
345-
return false;
346-
}
347-
348-
$calendars = $this->getCalendarsForPrincipal($principalUri);
349-
if (empty($calendars)) {
350-
$this->logger->warning('Could not find any calendars for principal ' . $principalUri);
384+
$this->logger->warning('iMip message event could not be processed because the event is in the past');
351385
return false;
352386
}
353387

@@ -369,14 +403,14 @@ public function handleIMipReply(
369403
}
370404

371405
if (empty($found)) {
372-
$this->logger->info('Event not found in any calendar for principal ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
406+
$this->logger->warning('iMip message event could not be processed because no corresponding event was found in any calendar ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
373407
return false;
374408
}
375409

376410
try {
377411
$found->handleIMipMessage($name, $calendarData); // sabre will handle the scheduling behind the scenes
378412
} catch (CalendarException $e) {
379-
$this->logger->error('Could not update calendar for iMIP processing', ['exception' => $e]);
413+
$this->logger->error('An error occurred while processing the iMip message event', ['exception' => $e]);
380414
return false;
381415
}
382416
return true;
@@ -393,29 +427,57 @@ public function handleIMipCancel(
393427
string $recipient,
394428
string $calendarData,
395429
): bool {
396-
/** @var VCalendar $vObject|null */
397-
$vObject = Reader::read($calendarData);
430+
431+
$calendars = $this->getCalendarsForPrincipal($principalUri);
432+
if (empty($calendars)) {
433+
$this->logger->warning('iMip message could not be processed because user has no calendars');
434+
return false;
435+
}
436+
437+
try {
438+
/** @var VCalendar $vObject|null */
439+
$vObject = Reader::read($calendarData);
440+
} catch (ParseException $e) {
441+
$this->logger->error('iMip message could not be processed because an error occurred while parsing the iMip message', ['exception' => $e]);
442+
return false;
443+
}
398444

399445
if ($vObject === null) {
446+
$this->logger->warning('iMip message contains an invalid calendar object');
447+
return false;
448+
}
449+
450+
if (!isset($vObject->METHOD) || $vObject->METHOD->getValue() !== 'CANCEL') {
451+
$this->logger->warning('iMip message contains an incorrect or invalid method');
452+
return false;
453+
}
454+
455+
if (!isset($vObject->VEVENT)) {
456+
$this->logger->warning('iMip message contains no event');
400457
return false;
401458
}
402459

403460
/** @var VEvent|null $vEvent */
404461
$vEvent = $vObject->{'VEVENT'};
405462

406-
if ($vEvent === null) {
463+
if (!isset($vEvent->UID)) {
464+
$this->logger->warning('iMip message event dose not contains a UID');
465+
return false;
466+
}
467+
468+
if (!isset($vEvent->ORGANIZER)) {
469+
$this->logger->warning('iMip message event dose not contains an organizer');
407470
return false;
408471
}
409472

410-
// First, we check if the correct method is passed to us
411-
if (strcasecmp('CANCEL', $vObject->{'METHOD'}->getValue()) !== 0) {
412-
$this->logger->warning('Wrong method provided for processing');
473+
if (!isset($vEvent->ATTENDEE)) {
474+
$this->logger->warning('iMip message event dose not contains any attendees');
413475
return false;
414476
}
415477

416478
$attendee = substr($vEvent->{'ATTENDEE'}->getValue(), 7);
417479
if (strcasecmp($recipient, $attendee) !== 0) {
418-
$this->logger->warning('Recipient must be an ATTENDEE of this event');
480+
$this->logger->warning('iMip message event could not be processed because recipient must be an ATTENDEE of this event');
419481
return false;
420482
}
421483

@@ -426,22 +488,15 @@ public function handleIMipCancel(
426488
$organizer = substr($vEvent->{'ORGANIZER'}->getValue(), 7);
427489
$isNotOrganizer = ($replyTo !== null) ? (strcasecmp($sender, $organizer) !== 0 && strcasecmp($replyTo, $organizer) !== 0) : (strcasecmp($sender, $organizer) !== 0);
428490
if ($isNotOrganizer) {
429-
$this->logger->warning('Sender must be the ORGANIZER of this event');
491+
$this->logger->warning('iMip message event could not be processed because sender must be the ORGANIZER of this event');
430492
return false;
431493
}
432494

433495
//check if the event is in the future
434496
/** @var DateTime $eventTime */
435497
$eventTime = $vEvent->{'DTSTART'};
436498
if ($eventTime->getDateTime()->getTimeStamp() < $this->timeFactory->getTime()) { // this might cause issues with recurrences
437-
$this->logger->warning('Only events in the future are processed');
438-
return false;
439-
}
440-
441-
// Check if we have a calendar to work with
442-
$calendars = $this->getCalendarsForPrincipal($principalUri);
443-
if (empty($calendars)) {
444-
$this->logger->warning('Could not find any calendars for principal ' . $principalUri);
499+
$this->logger->warning('iMip message event could not be processed because the event is in the past');
445500
return false;
446501
}
447502

@@ -463,17 +518,15 @@ public function handleIMipCancel(
463518
}
464519

465520
if (empty($found)) {
466-
$this->logger->info('Event not found in any calendar for principal ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
467-
// this is a safe operation
468-
// we can ignore events that have been cancelled but were not in the calendar anyway
469-
return true;
521+
$this->logger->warning('iMip message event could not be processed because no corresponding event was found in any calendar ' . $principalUri . 'and UID' . $vEvent->{'UID'}->getValue());
522+
return false;
470523
}
471524

472525
try {
473526
$found->handleIMipMessage($name, $calendarData); // sabre will handle the scheduling behind the scenes
474527
return true;
475528
} catch (CalendarException $e) {
476-
$this->logger->error('Could not update calendar for iMIP processing', ['exception' => $e]);
529+
$this->logger->error('An error occurred while processing the iMip message event', ['exception' => $e]);
477530
return false;
478531
}
479532
}

0 commit comments

Comments
 (0)