bitfireAT/ical4android

Arabic ZoneOffset cannot be parsed

Closed this issue · 4 comments

This has been discussed in disc-257, however, I wanted to keep track of this issue separately, just to keep track on the progress.

This issue is really related to ical4j/ical4j#458, however, since that issue has been stale since 2020, maybe we can make a workaround. I think this is an issue that might affect a lot of users that are not in the "English-speaking" timezones.

Just by searching around Google, I managed to find a Java function that converts all the arabic characters to decimal. I've converted that function to Kotlin:

/**
 * Converts an string with arabic numbers to their decimal equivalents.
 * @param number The number to convert.
 * @return An string that has all the arabic numbers found in [number] replaced by their English
 * representations.
 */
fun arabicToDecimal(number: String): String {
    val chars = CharArray(number.length)
    for (i in number.indices) {
        var ch = number[i].code
        if (ch in 0x0660..0x669)
            ch -= 0x0660 - '0'.code
        else if (ch in 0x06f0..0x06F9)
            ch -= 0x06f0 - '0'.code
        chars[i] = ch.toChar()
    }
    return String(chars)
}

By adding this to MiscUtils, this test:

@Test
fun testArabicToDecimal() {
    val arabic = "+۰۳۲۵۴۴"
    val decimal = MiscUtils.arabicToDecimal(arabic)
    assertEquals(decimal, "+032544")
}

shows that the function works properly. We can also use a website like this to check if the conversion is correct, which as far as I'm concerned, it works correctly.

Now the next step would be to add this conversion to the calendar parser. We can't, however, convert the whole calendar, since if the user has numbers in their event name, for example, they would be replaced by the decimal representations, which I don't think is a good option. We should search for all the properties that have the Time Zone type, and replace their values.

I'm not sure where to make this change, since, first, we should make a test that doesn't pass because of this. Here

// add VTIMEZONE components
for (tz in usedTimeZones)
ical.components += minifyVTimeZone(tz.vTimeZone, earliest)

Maybe it's too late, and the error has already been thrown, and we should really work it out in ICalendar, otherwise the error might still occur. However, it's difficult to replace the Timezone properties without having parsed the calendar before, so running the fix on ICalendar.fromReader may be too early...

I will keep investigating. What do you think @rfc2822 ?

Hm I don't see any bug here, except if ical4j/ical4android would generate such invalid VTIMEZONEs. Is this the case?

If it's only about parsing, we can forget about it, because then the iCalendars with those numbers are simply invalid (and probably generated by some obsolete DAVx5 version) and we should get rid of the existing ones and then forget it.

If it's only about parsing, we can forget about it, because then the iCalendars with those numbers are simply invalid (and probably generated by some obsolete DAVx5 version) and we should get rid of the existing ones and then forget it.

Yup, seems like a problem of parsing. I have been trying to reproduce the error said by the user, but I can't manage to do so, even with the steps given, so I suppose it's an error from the server.

Then I suggest that we try to obtain the specific iCalendar that causes the sync error and have a look at it (especially the PRODID). If it was an old DAVx⁵, we can forget about it and just help the user to migrate the events.

Closing since already reported in ical4j#458