Skip to content

Commit

Permalink
tests: add testcase for DESK-2104
Browse files Browse the repository at this point in the history
References: DESK-2104, GXF-1819
  • Loading branch information
jengelh committed Sep 30, 2024
1 parent 5ccb750 commit 346bde7
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 1 deletion.
9 changes: 8 additions & 1 deletion include/gromox/mapitags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1170,27 +1170,32 @@ enum {
PidLidTaskFRecurring = 0x8126,

/* PSETID_Appointment */
PidLidSendMeetingAsIcal = 0x8200,
PidLidAppointmentSequence = 0x8201,
PidLidBusyStatus = 0x8205,
PidLidLocation = 0x8208,
PidLidAppointmentReplyTime = 0x8220,
PidLidAppointmentStartWhole = 0x820D,
PidLidAppointmentEndWhole = 0x820E,
PidLidAppointmentDuration = 0x8213,
PidLidAppointmentSubType = 0x8215,
PidLidAppointmentRecur = 0x8216,
PidLidAppointmentStateFlags = 0x8217,
PidLidResponseStatus = 0x8218,
PidLidAppointmentReplyTime = 0x8220,
PidLidRecurring = 0x8223, /* this object is a recurring series */
PidLidIntendedBusyStatus = 0x8224,
PidLidExceptionReplaceTime = 0x8228,
PidLidFInvited = 0x8229,
PidLidAppointmentReplyName = 0x8230,
PidLidRecurrenceType = 0x8231,
PidLidRecurrencePattern = 0x8232,
PidLidTimeZoneStruct = 0x8233,
PidLidTimeZoneDescription = 0x8234,
PidLidClipStart = 0x8235,
PidLidClipEnd = 0x8236,
PidLidAllAttendeesString = 0x8238,
PidLidToAttendeesString = 0x823B,
PidLidCcAttendeesString = 0x823C,
PidLidAppointmentProposedStartWhole = 0x8250,
PidLidAppointmentProposedEndWhole = 0x8251,
PidLidAppointmentCounterProposal = 0x8257,
Expand All @@ -1211,9 +1216,11 @@ enum {
PidLidReminderTime = 0x8502,
PidLidReminderSet = 0x8503,
PidLidPrivate = 0x8506,
PidLidSideEffects = 0x8510,
PidLidSmartNoAttach = 0x8514,
PidLidCommonStart = 0x8516,
PidLidCommonEnd = 0x8517,
PidLidTaskMode = 0x8518,
PidLidFlagRequest = 0x8530,
PidLidMileage = 0x8534, // not in ms-oxprops
PidLidBilling = 0x8535,
Expand Down
87 changes: 87 additions & 0 deletions tests/oxcmail_ie.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
// SPDX-FileCopyrightText: 2024 grommunio GmbH
// This file is part of Gromox.
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <libHX/string.h>
#include <gromox/element_data.hpp>
#include <gromox/ical.hpp>
#include <gromox/oxcmail.hpp>
#include <gromox/util.hpp>
#include "../tools/staticnpmap.cpp"
Expand Down Expand Up @@ -309,6 +311,90 @@ static int select_parts_5()
return 0;
}

static void ical_export_1()
{
/*
* DESK-2104: Old Zarafa imports (which lack some TZ fields) shifted by
* one day in some MUA, attributed to DTSTART not containing any TZID
* but just UTC.
*/
const struct {
uint16_t proptag;
PROPERTY_NAME pn;
} ee_map[] = {
{0x8002, {MNID_ID, PSETID_Meeting, 2}},
{0x8003, {MNID_ID, PSETID_Meeting, 3}},
{0x801b, {MNID_ID, PSETID_Meeting, 23}},
{0x8091, {MNID_ID, PSETID_Appointment, PidLidSendMeetingAsIcal}},
{0x8096, {MNID_ID, PSETID_Appointment, PidLidBusyStatus}},
{0x8099, {MNID_ID, PSETID_Appointment, PidLidLocation}},
{0x809d, {MNID_ID, PSETID_Appointment, PidLidAppointmentStartWhole}},
{0x809e, {MNID_ID, PSETID_Appointment, PidLidAppointmentEndWhole}},
{0x80a3, {MNID_ID, PSETID_Appointment, PidLidAppointmentDuration}},
{0x80a5, {MNID_ID, PSETID_Appointment, PidLidAppointmentSubType}},
{0x80a7, {MNID_ID, PSETID_Appointment, PidLidAppointmentStateFlags}},
{0x80a8, {MNID_ID, PSETID_Appointment, PidLidResponseStatus}},
{0x80a9, {MNID_ID, PSETID_Appointment, PidLidAppointmentReplyTime}},
{0x80aa, {MNID_ID, PSETID_Appointment, PidLidRecurring}},
{0x80ab, {MNID_ID, PSETID_Appointment, PidLidIntendedBusyStatus}},
{0x80af, {MNID_ID, PSETID_Appointment, PidLidFInvited}},
{0x80b5, {MNID_ID, PSETID_Appointment, PidLidAppointmentReplyName}},
{0x80b8, {MNID_ID, PSETID_Appointment, PidLidTimeZoneStruct}},
{0x80b9, {MNID_ID, PSETID_Appointment, PidLidTimeZoneDescription}},
{0x80bd, {MNID_ID, PSETID_Appointment, PidLidAllAttendeesString}},
{0x80bf, {MNID_ID, PSETID_Appointment, PidLidToAttendeesString}},
{0x80c0, {MNID_ID, PSETID_Appointment, PidLidCcAttendeesString}},
{0x80e1, {MNID_ID, PSETID_Common, PidLidReminderSet}},
{0x80e4, {MNID_ID, PSETID_Common, PidLidPrivate}},
{0x80e6, {MNID_ID, PSETID_Common, PidLidSideEffects}},
{0x80e9, {MNID_ID, PSETID_Common, PidLidCommonStart}},
{0x80ea, {MNID_ID, PSETID_Common, PidLidCommonEnd}},
{0x80eb, {MNID_ID, PSETID_Common, PidLidTaskMode}},
};
auto lo_get_propids = [&](const PROPNAME_ARRAY *pna, PROPID_ARRAY *idp) -> BOOL {
auto &id = *idp;
id.resize(pna->size());
for (size_t i = 0; i < pna->size(); ++i) {
auto row = std::find_if(std::cbegin(ee_map), std::cend(ee_map),
[&](const auto &r) -> bool { return r.pn == (*pna)[i]; });
id[i] = row != std::cend(ee_map) ? row->proptag : 0;
}
return TRUE;
};
static constexpr uint64_t v_time = 0x1dabd02f773da00;
const BINARY bin_92{92, {reinterpret_cast<uint8_t *>(deconst("\4\0\0\0\202\0\340\0t\305\267\20\32\202\340\b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\04\0\0\0vCal-Uid\1\0\0\0hebcal-20240612T215900-a35a8505-2761369\0"))}};
const BINARY bin_48{48, {reinterpret_cast<uint8_t *>(deconst("\304\377\377\377\0\0\0\0\304\377\377\377\0\0\0\0\n\0\0\0\5\0\3\0\0\0\0\0\0\0\0\0\0\0\3\0\0\0\5\0\2\0\0\0\0\0\0\0"))}};
const TAGGED_PROPVAL props[] = {
{PR_MESSAGE_CLASS, deconst("IPM.Appointment")},
{PR_START_DATE, deconst(&v_time)},
{PR_END_DATE, deconst(&v_time)},
{0x80030102, deconst(&bin_92)},
{0x801b0102, deconst(&bin_92)},
{0x809d0040, deconst(&v_time)},
{0x809e0040, deconst(&v_time)},
{0x80b80102, deconst(&bin_48)},
{0x80b9001f, deconst("Europe/Vienna")},
};
const MESSAGE_CONTENT msgctnt = {{std::size(props), deconst(props)}};
ical icalout;
fprintf(stderr, "=== ical_export_1\n");
if (!oxcical_export(&msgctnt, icalout, "x500org", malloc, lo_get_propids, nullptr)) {
fprintf(stderr, "oxcical_export failed\n");
return;
}
std::string icstr;
if (icalout.serialize(icstr) != ecSuccess) {
fprintf(stderr, "ical_serialize failed\n");
return;
}
constexpr char needle[] = "DTSTART;TZID=Europe/Vienna:20240612T215900";
auto ptr = strstr(icstr.c_str(), needle);
if (ptr == nullptr) {
printf("%s\n", icstr.c_str());
fprintf(stderr, "FAILED. Substrings Europe/215900 not found.\n");
}
}

int main()
{
auto ee_get_user_ids = [](const char *, unsigned int *, unsigned int *, enum display_type *) -> BOOL { return false; };
Expand All @@ -324,5 +410,6 @@ int main()
select_parts_3();
select_parts_4();
select_parts_5();
ical_export_1();
return EXIT_SUCCESS;
}

0 comments on commit 346bde7

Please sign in to comment.