mangstadt / ez-vcard

A vCard parser library for Java
Other
405 stars 93 forks source link

Invalid value for "MonthOfYear" caused by wrong BDAY date #134

Closed devvv4ever closed 1 year ago

devvv4ever commented 1 year ago

Hello!

thanks for maintaining this library!

We've got a report by a user where the server sent a wrong value for the birthday:

BDAY:19879215

which resulted in

EXCEPTION j$.time.DateTimeException: Invalid value for MonthOfYear (valid values 1 - 12): 92

The birthday is obviously using a wrong date (no 92nd month exists). Maybe parsing these kind of dates should be ignored?

This is the full stack trace:

EXCEPTION
j$.time.DateTimeException: Invalid value for MonthOfYear (valid values 1 - 12): 92
    at j$.time.temporal.ValueRange.b(Unknown Source:13)
    at j$.time.temporal.ChronoField.L(Unknown Source:4)
    at j$.time.LocalDate.of(Unknown Source:9)
    at ezvcard.io.scribe.VCardPropertyScribe.date(VCardPropertyScribe.java:6)
    at ezvcard.io.scribe.DateOrTimePropertyScribe.parse(DateOrTimePropertyScribe.java:1)
    at ezvcard.io.scribe.DateOrTimePropertyScribe._parseText(DateOrTimePropertyScribe.java:7)
    at ezvcard.io.scribe.DateOrTimePropertyScribe._parseText(DateOrTimePropertyScribe.java:1)
    at ezvcard.io.scribe.VCardPropertyScribe.parseText(VCardPropertyScribe.java:1)
    at ezvcard.io.text.VCardReader._readNext(VCardReader.java:1047)
    at ezvcard.io.StreamReader.readNext(StreamReader.java:13)
    at at.bitfire.vcard4android.Contact$Companion.fromReader(Contact.kt:58)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager.processCard(ContactsSyncManager.kt:26)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager.access$processCard(ContactsSyncManager.kt:1)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager$downloadRemote$1$1$1.invoke(ContactsSyncManager.kt:10)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager$downloadRemote$1$1$1.invoke(ContactsSyncManager.kt:1)
    at at.bitfire.davdroid.syncadapter.SyncManager.responseExceptionContext(SyncManager.kt:13)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager$downloadRemote$1.invoke$lambda$0(ContactsSyncManager.kt:21)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager$downloadRemote$1.$r8$lambda$aTmx16DT01n3ZmMyYWepKV6Txjc(ContactsSyncManager.kt:1)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager$downloadRemote$1$$ExternalSyntheticLambda0.onResponse(R8$$SyntheticClass:3)
    at at.bitfire.dav4jvm.Response$Companion.parse(Response.kt:306)
    at at.bitfire.dav4jvm.DavResource.processMultiStatus$parseMultiStatus(DavResource.kt:51)
    at at.bitfire.dav4jvm.DavResource.processMultiStatus(DavResource.kt:16)
    at at.bitfire.dav4jvm.DavResource.processMultiStatus(DavResource.kt:9)
    at at.bitfire.dav4jvm.DavAddressBook.multiget(DavAddressBook.kt:67)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager$downloadRemote$1.invoke(ContactsSyncManager.kt:10)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager$downloadRemote$1.invoke(ContactsSyncManager.kt:1)
    at at.bitfire.davdroid.syncadapter.SyncManager.remoteExceptionContext(SyncManager.kt:1)
    at at.bitfire.davdroid.syncadapter.SyncManager.remoteExceptionContext(SyncManager.kt:5)
    at at.bitfire.davdroid.syncadapter.ContactsSyncManager.downloadRemote(ContactsSyncManager.kt:46)
    at at.bitfire.davdroid.syncadapter.SyncManager$syncRemote$1$download$1.invokeSuspend(SyncManager.kt:12)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:9)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:107)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:154)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:103)
    at at.bitfire.davdroid.syncadapter.SyncManager.syncRemote(SyncManager.kt:41)
    at at.bitfire.davdroid.syncadapter.SyncManager$performSync$1.invoke(SyncManager.kt:46)
    at at.bitfire.davdroid.syncadapter.SyncManager$performSync$1.invoke(SyncManager.kt:1)
    at at.bitfire.davdroid.syncadapter.SyncManager.unwrapExceptions(SyncManager.kt:2)
    at at.bitfire.davdroid.syncadapter.SyncManager.performSync(SyncManager.kt:20)
    at at.bitfire.davdroid.syncadapter.ContactsSyncAdapterService$ContactsSyncAdapter.sync(ContactsSyncAdapterService.kt:246)
    at at.bitfire.davdroid.syncadapter.SyncAdapterService$SyncAdapter$onPerformSync$1.invoke(SyncAdapterService.kt:8)
    at at.bitfire.davdroid.syncadapter.SyncAdapterService$SyncAdapter$onPerformSync$1.invoke(SyncAdapterService.kt:1)
    at at.bitfire.davdroid.util.ConcurrentUtils.runSingle(ConcurrentUtils.kt:21)
    at at.bitfire.davdroid.syncadapter.SyncAdapterService$SyncAdapter.onPerformSync(SyncAdapterService.kt:108)
    at at.bitfire.davdroid.syncadapter.SyncWorker.doWork(SyncWorker.kt:321)
    at androidx.work.Worker$1.run(Worker.java:3)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)

The user needed to manually correct the vcf in this case, then it started to work again. Although this wrong BDAY value should have never been accepted or found it's way into the servers vcf database, I think ignoring such values could improve the general workflow.

Thank you and kind regards! Bernhard / DAVx⁵

mangstadt commented 1 year ago

Thanks for reporting this! ez-vcard will now log a warning instead of throwing a DateTimeException.

https://github.com/mangstadt/ez-vcard/blob/master/src/test/java/ezvcard/issue/Issue134.java

See also: https://github.com/mangstadt/biweekly/issues/121