mangstadt/ez-vcard

Invalid value for "MonthOfYear" caused by wrong BDAY date

Closed this issue · 1 comments

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⁵

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: mangstadt/biweekly#121