arran4 / golang-ical

A ICS / ICal parser and serialiser for Golang.
Apache License 2.0
310 stars 73 forks source link

error:malformed calendar; expected end #111

Closed KirillZet closed 1 week ago

KirillZet commented 2 weeks ago

Current Behavior:

Hello, I'm trying to parse a calendar using your library. Calendar obtained via http. Here's my code:

icalURL := "http://english.mirea.ru/schedule/api/ical/1/248"

resp, err := http.Get(icalURL)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

fmt.Println("Raw iCal data:")
body, err := io.ReadAll(resp.Body)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(body))

calendar, err := ics.ParseCalendar(strings.NewReader(string(body)))
if err != nil {
    log.Fatal(err)
}

fmt.Println(calendar)

Calendar is nil and error “malformed calendar; expected end”

Expected Behavior:

I tested parsing this calendar(from the same link) in python using the library icalendar, everything parsed as I needed it to.

Steps To Reproduce:

Minimal Example ical extract:

BEGIN:VCALENDAR
PRODID:-//github.com/rianjs/ical.net//NONSGML ical.net 4.0//EN
VERSION:2.0
X-WR-CALNAME:БСБО-01-21
BEGIN:VTIMEZONE
TZID:Europe/Moscow
X-LIC-LOCATION:Europe/Moscow
BEGIN:STANDARD
TZOFFSETFROM:+0300
TZOFFSETTO:+0300
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTEND;TZID=Europe/Moscow;VALUE=DATE:20240324
DTSTAMP;TZID=Europe/Moscow:00010101T000000
DTSTART;TZID=Europe/Moscow;VALUE=DATE:20240323
SEQUENCE:0
SUMMARY:Все занятия в дистанционном формате
TRANSP:TRANSPARENT
UID:c68bc5ec-e46f-55ae-9f0a-9cea4365dc9b
END:VEVENT
BEGIN:VEVENT
CATEGORIES:ЛК
DESCRIPTION:Преподаватель: Корягин Сергей Викторович\n\nГруппы:\nБСБО-01-2
 1\nБСБО-02-21\nБСБО-04-21\n
DTEND;TZID=Europe/Moscow:20240902T121000
DTSTAMP:00010101T000000
DTSTART;TZID=Europe/Moscow:20240902T104000
LOCATION:455 (С-20)
RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20241230T210000Z
SEQUENCE:0
SUMMARY:ЛК Создание инструментальных средств разработки программного обесп
 ечения
TRANSP:OPAQUE
UID:f9de3adf-37f2-5710-abaf-27bd64443c70
X-SCHEDULE_VERSION-ID:8
END:VEVENT
BEGIN:X-SCHEDULE-VERSION
SVID:8
X-SV-END:2024-12-30T21:00:00.0000000Z
X-SV-START:2024-09-01T21:00:00.0000000Z
X-SV-TYPE:SEMESTER
END:X-SCHEDULE-VERSION
END:VCALENDAR

Anything else:

icalURL := "http://english.mirea.ru/schedule/api/ical/1/248"

arran4 commented 1 week ago

Will do a small test now. See if it can be quickly resolved.

arran4 commented 1 week ago

@KirillZet The issue is the _ in this line:

X-SCHEDULE_VERSION-ID:8

Tests:

https://github.com/arran4/golang-ical/blob/5670d8a3f3650007bb5b3b827b7a3aead774480d/calendar_test.go#L497-L525

Broken: https://github.com/arran4/golang-ical/blob/5670d8a3f3650007bb5b3b827b7a3aead774480d/testdata/issue111/vevent2.ics

Working: https://github.com/arran4/golang-ical/blob/5670d8a3f3650007bb5b3b827b7a3aead774480d/testdata/issue111/vevent2.ics

Which should follow the grammar: https://datatracker.ietf.org/doc/html/rfc5545

(I have extracted it to the relevant parts from section 3.1)

     name          = iana-token / x-name
     x-name        = "X-" [vendorid "-"] 1*(ALPHA / DIGIT / "-")
     vendorid      = 3*(ALPHA / DIGIT)

Alpha and digit are defined in:

     ALPHA      = %x41-5A / %x61-7A   ; A-Z / a-z
     DIGIT      = %x30-39

Which I know sucks as an answer.

How much influence do you have over this choice of character? I will see if we can find a solution. It's not per-say a "bug" in this but I do feel that if a work around is possible I could try offer it.

I don't know ical.net should we ping the developer? https://github.com/ical-org/ical.net

RegreTTO commented 1 week ago

Broken: https://github.com/arran4/golang-ical/blob/5670d8a3f3650007bb5b3b827b7a3aead774480d/testdata/issue111/vevent2.ics

Working: https://github.com/arran4/golang-ical/blob/5670d8a3f3650007bb5b3b827b7a3aead774480d/testdata/issue111/vevent2.ics

It seems, that your provided examples are the same

arran4 commented 1 week ago

Hah.. Clipboard failure.

Try one of those against working: https://github.com/arran4/golang-ical/blob/5670d8a3f3650007bb5b3b827b7a3aead774480d/testdata/issue111/vevent2-no-desc.ics

Remember, always ^C at least 2 times. :P

KirillZet commented 1 week ago

Thanks for the help) I just replaced this line everywhere X-SCHEDULE_VERSION-ID:8, with this X-SCHEDULE-VERSION-ID, and everything parsed as it should.

bodyString = strings.Replace(bodyString, "X-SCHEDULE_VERSION-ID:8", "X-SCHEDULE-VERSION-ID:8", -1)

I think everyone who faces the same problem can solve it this way. It's a bit of a crutch, but it works)

KirillZet commented 1 week ago

Could be in func ParseCalendar(r io.Reader) (*Calendar, error) replace string before parsing to avoid problems with this format

arran4 commented 1 week ago

I think this ticket indicates 2 issues with my library:

So expect improvements.

@KirillZet were you able to find where the invalid token (name X-SCHEDULE_VERSION-ID:8) was being inserted? What's generating it?

KirillZet commented 1 week ago

I think this ticket indicates 2 issues with my library:

So expect improvements.

@KirillZet were you able to find where the invalid token (name X-SCHEDULE_VERSION-ID:8) was being inserted? What's generating it?

The API from which I get the link to ical belongs to my university, so there's no way for me to see what's actually going on there.

arran4 commented 1 week ago

Ah. I guess all you can do is log it. Good luck.