sync(chunk 2a): vendor dav4jvm 2.2.1 as :dav
JitPack-only publishing conflicts with FAIL_ON_PROJECT_REPOS, artifacts are unsigned and not immutable, and upstream shipped two breaking majors 19 days apart. 2.2.1 is the last OkHttp release: 3.0.0 moved to Ktor and 4.x needs Java 21, and SYNC.md's whole auth section is written in OkHttp terms, so 4.x would have invalidated it. A plain JVM module, not an Android library — the tree has no Android imports and keeping it that way keeps the floret-kit extraction a file move. Four changes from upstream, all in dav/PROVENANCE.md: - commons-lang3 dropped (one import, one call). The replacement requires the whole string to be consumed, as DateUtils did: pattern 1 ends in a literal 'GMT', so SimpleDateFormat would match "...GMT+02:00" as a prefix and throw the offset away. - HTTP dates were parsed and formatted in the device's local zone — the GMT in the format string is a quoted literal and timeZone was never set, so every getlastmodified was out by the local UTC offset. Upstream tests dates nowhere. The formatter is also no longer shared and mutable. - dav4jvm#209: permanent redirects now reach the caller via DavResource.permanentLocation, cleared per request so it never describes an earlier one. - xpp3 is compileOnly; Android supplies org.xmlpull.v1. SYNC.md's other claimed defect, "does not follow 303", is not true of 2.2.1 — pinned by a test rather than removed from the notes. CI names :dav:test explicitly; testDebugUnitTest is Android-only and would have run none of the vendored suite. lintDebug added to the per-chunk checks after it caught a literal byte-order mark left by chunk 1.
This commit is contained in:
@@ -182,6 +182,15 @@ dependencies {
|
||||
// API surface, so it isn't declared separately.
|
||||
implementation(libs.dmfs.lib.recur)
|
||||
|
||||
// Vendored dav4jvm — the CalDAV protocol layer. See dav/PROVENANCE.md.
|
||||
implementation(project(":dav"))
|
||||
// :dav gets org.xmlpull.v1 from the Android framework at runtime and declares
|
||||
// xpp3 compileOnly, which is not transitive. Unit tests run on a plain JVM
|
||||
// with no framework, and android.jar's stub factory returns null under
|
||||
// isReturnDefaultValues — so anything touching XmlUtils would NPE without a
|
||||
// real implementation here.
|
||||
testImplementation(libs.xpp3)
|
||||
|
||||
implementation(libs.androidx.room.runtime)
|
||||
implementation(libs.androidx.room.ktx)
|
||||
ksp(libs.androidx.room.compiler)
|
||||
|
||||
@@ -15,6 +15,13 @@ package de.jeanlucmakiola.agendula.domain.ical
|
||||
*/
|
||||
object ICalParser {
|
||||
|
||||
/**
|
||||
* Written as an escape, not as the character itself: a literal BOM anywhere
|
||||
* but byte 0 of a file is what Android Lint's `ByteOrderMark` check exists to
|
||||
* catch, and it fails the build.
|
||||
*/
|
||||
private const val BOM = "\uFEFF"
|
||||
|
||||
fun parse(text: String): ICalComponent =
|
||||
parseAll(text).firstOrNull() ?: throw ICalParseException("no component found")
|
||||
|
||||
@@ -67,7 +74,7 @@ object ICalParser {
|
||||
*/
|
||||
internal fun unfold(text: String): List<String> {
|
||||
val lines = mutableListOf<StringBuilder>()
|
||||
val normalised = text.removePrefix("")
|
||||
val normalised = text.removePrefix(BOM)
|
||||
for (raw in normalised.split("\r\n", "\n", "\r")) {
|
||||
if (raw.isEmpty()) continue
|
||||
val continuation = raw[0] == ' ' || raw[0] == '\t'
|
||||
|
||||
@@ -35,7 +35,7 @@ class ICalParserTest {
|
||||
|
||||
@Test
|
||||
fun `a leading BOM is stripped rather than glued onto the first name`() {
|
||||
val component = ICalParser.parse("BEGIN:VTODO\r\nUID:x\r\nEND:VTODO\r\n")
|
||||
val component = ICalParser.parse("\uFEFFBEGIN:VTODO\r\nUID:x\r\nEND:VTODO\r\n")
|
||||
assertThat(component.name).isEqualTo("VTODO")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user