From 4813d4313b0b6c8afddf12ef60fc1dea4072558c Mon Sep 17 00:00:00 2001 From: alperozturk Date: Fri, 9 Feb 2024 10:40:29 +0100 Subject: [PATCH 1/7] Handle potential cast error, use extension Signed-off-by: alperozturk --- .../extensions/ArrayListExtensions.kt | 20 +++++++++++ .../android/lib/common/network/WebdavEntry.kt | 35 ++++++------------- 2 files changed, 31 insertions(+), 24 deletions(-) create mode 100644 library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt diff --git a/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt b/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt new file mode 100644 index 000000000..235f652da --- /dev/null +++ b/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt @@ -0,0 +1,20 @@ +package com.nextcloud.extensions + +import org.w3c.dom.Element + +inline fun ArrayList<*>.processXmlData(tagName: String): T? { + this.forEach { + val element = it as? Element + if (element != null && element.tagName == tagName) { + val textContent = element.firstChild.textContent + + return when (T::class) { + Float::class -> textContent.toDouble() as T + Double::class -> textContent.toDouble() as T + else -> textContent as T + } + } + } + + return null +} diff --git a/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt b/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt index 6906b44e4..6c4d3b9fd 100644 --- a/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt +++ b/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt @@ -26,6 +26,7 @@ package com.owncloud.android.lib.common.network import android.net.Uri import com.google.gson.Gson import com.nextcloud.extensions.fromDavProperty +import com.nextcloud.extensions.processXmlData import com.owncloud.android.lib.common.utils.Log_OC import com.owncloud.android.lib.resources.files.model.FileLockType import com.owncloud.android.lib.resources.files.model.FileLockType.Companion.fromValue @@ -428,19 +429,12 @@ class WebdavEntry constructor(ms: MultiStatusResponse, splitElement: String) { prop = propSet[EXTENDED_PROPERTY_METADATA_SIZE, ncNamespace] gson.fromDavProperty(prop) } else { - val xmlData = prop.value as ArrayList<*> - var width = 0f - var height = 0f - xmlData.forEach { - val element = it as Element - if (element.tagName == "width") { - width = element.firstChild.textContent.toFloat() - } else if (element.tagName == "height") { - height = element.firstChild.textContent.toFloat() - } - } + val result = ImageDimension() + val xmlData = prop.value as? ArrayList<*> + result.width = xmlData?.processXmlData("width") ?: -1f + result.height = xmlData?.processXmlData("height") ?: -1f - ImageDimension(width, height) + result } // NC metadata gps property @@ -450,19 +444,12 @@ class WebdavEntry constructor(ms: MultiStatusResponse, splitElement: String) { prop = propSet[EXTENDED_PROPERTY_METADATA_GPS, ncNamespace] gson.fromDavProperty(prop) } else { - val xmlData = prop.value as ArrayList<*> - var latitude = 0.0 - var longitude = 0.0 - xmlData.forEach { - val element = it as Element - if (element.tagName == "latitude") { - latitude = element.firstChild.textContent.toDouble() - } else if (element.tagName == "longitude") { - longitude = element.firstChild.textContent.toDouble() - } - } + val result = GeoLocation() + val xmlData = prop.value as? ArrayList<*> + result.latitude = xmlData?.processXmlData("latitude") ?: -1.0 + result.longitude = xmlData?.processXmlData("longitude") ?: -1.0 - GeoLocation(latitude, longitude) + result } // NC metadata live photo property: From 5b7c8e929b995de26b32a0a905c2d46901a8c474 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Fri, 9 Feb 2024 11:10:54 +0100 Subject: [PATCH 2/7] Add fallback scenario for new way Signed-off-by: alperozturk --- .../android/lib/common/network/WebdavEntry.kt | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt b/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt index 6c4d3b9fd..598e53c34 100644 --- a/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt +++ b/library/src/main/java/com/owncloud/android/lib/common/network/WebdavEntry.kt @@ -429,12 +429,16 @@ class WebdavEntry constructor(ms: MultiStatusResponse, splitElement: String) { prop = propSet[EXTENDED_PROPERTY_METADATA_SIZE, ncNamespace] gson.fromDavProperty(prop) } else { - val result = ImageDimension() val xmlData = prop.value as? ArrayList<*> - result.width = xmlData?.processXmlData("width") ?: -1f - result.height = xmlData?.processXmlData("height") ?: -1f + val width = xmlData?.processXmlData("width") + val height = xmlData?.processXmlData("height") - result + if (width != null && height != null) { + ImageDimension(width, height) + } else { + prop = propSet[EXTENDED_PROPERTY_METADATA_SIZE, ncNamespace] + gson.fromDavProperty(prop) + } } // NC metadata gps property @@ -444,12 +448,16 @@ class WebdavEntry constructor(ms: MultiStatusResponse, splitElement: String) { prop = propSet[EXTENDED_PROPERTY_METADATA_GPS, ncNamespace] gson.fromDavProperty(prop) } else { - val result = GeoLocation() val xmlData = prop.value as? ArrayList<*> - result.latitude = xmlData?.processXmlData("latitude") ?: -1.0 - result.longitude = xmlData?.processXmlData("longitude") ?: -1.0 + val latitude = xmlData?.processXmlData("latitude") + val longitude = xmlData?.processXmlData("longitude") - result + if (latitude != null && longitude != null) { + GeoLocation(latitude, longitude) + } else { + prop = propSet[EXTENDED_PROPERTY_METADATA_GPS, ncNamespace] + gson.fromDavProperty(prop) + } } // NC metadata live photo property: From 86f8da66ae67e509556400673ea4712a2c498c67 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Fri, 9 Feb 2024 14:59:25 +0100 Subject: [PATCH 3/7] Fix processXmlData generic fun Signed-off-by: alperozturk --- .../main/java/com/nextcloud/extensions/ArrayListExtensions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt b/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt index 235f652da..96afbb473 100644 --- a/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt +++ b/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt @@ -9,7 +9,7 @@ inline fun ArrayList<*>.processXmlData(tagName: String): T? { val textContent = element.firstChild.textContent return when (T::class) { - Float::class -> textContent.toDouble() as T + Float::class -> textContent.toFloat() as T Double::class -> textContent.toDouble() as T else -> textContent as T } From cae57946df6a1801965eee3bc8dc316f08a16d0f Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 19 Feb 2024 10:05:26 +0100 Subject: [PATCH 4/7] Add XmlDataProcessorTest Signed-off-by: alperozturk --- .../extensions/XmlDataProcessorTest.kt | 81 +++++++++++++++++++ .../extensions/ArrayListExtensions.kt | 12 ++- 2 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 library/src/androidTest/java/com/nextcloud/extensions/XmlDataProcessorTest.kt diff --git a/library/src/androidTest/java/com/nextcloud/extensions/XmlDataProcessorTest.kt b/library/src/androidTest/java/com/nextcloud/extensions/XmlDataProcessorTest.kt new file mode 100644 index 000000000..aa96be24e --- /dev/null +++ b/library/src/androidTest/java/com/nextcloud/extensions/XmlDataProcessorTest.kt @@ -0,0 +1,81 @@ +package com.nextcloud.extensions + +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test +import org.w3c.dom.Element +import javax.xml.parsers.DocumentBuilderFactory + +class XmlDataProcessorTest { + + @Test + fun testProcessXmlDataWhenGivenEmptyArrayListShouldReturnNull() { + val tag = "width" + val xmlData: ArrayList = arrayListOf() + val result = xmlData.processXmlData(tag) + assertNull(result) + } + + @Test + fun testProcessXmlDataWhenGivenWrongArrayListShouldReturnNull() { + val tag = "width" + val xmlData: ArrayList = arrayListOf("element") + val result = xmlData.processXmlData(tag) + assertNull(result) + } + + @Test + fun testProcessXmlDataWhenGivenValidDataShouldReturnFloat() { + val tag = "width" + val element = createElement(tag, "220") + val xmlData: ArrayList = arrayListOf(element) + val result = xmlData.processXmlData(tag) + assertEquals(220f, result) + } + + @Test + fun testProcessXmlDataWhenGivenValidDataAndWrongTagShouldReturnNull() { + val element = createElement("width", "220") + val xmlData: ArrayList = arrayListOf(element) + val result = xmlData.processXmlData("latitude") + assertNull(result) + } + + @Test + fun testProcessXmlDataWhenGivenNullElementShouldReturnNull() { + val tag = "width" + val xmlData: ArrayList = arrayListOf(null) + val result = xmlData.processXmlData(tag) + assertNull(result) + } + + @Test + fun testProcessXmlDataWhenGivenValidDataShouldReturnDouble() { + val tag = "latitude" + val element = createElement(tag, "12.4231") + val xmlData: ArrayList = arrayListOf(element) + val result = xmlData.processXmlData(tag) + assertEquals(12.4231, result) + } + + @Test + fun testProcessXmlDataWhenGivenDifferentValueTypeShouldReturnNull() { + val tag = "latitude" + val element = createElement(tag, "StringData") + val xmlData: ArrayList = arrayListOf(element) + val result = xmlData.processXmlData(tag) + assertNull(result) + } + + private fun createElement(xml: String, value: String): Element { + val builder = DocumentBuilderFactory.newInstance().run { + newDocumentBuilder() + } + val document = builder.newDocument() + val element = document.createElement(xml).apply { + textContent = value + } + document.appendChild(element) + return element + } +} diff --git a/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt b/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt index 96afbb473..16851b27f 100644 --- a/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt +++ b/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt @@ -9,9 +9,15 @@ inline fun ArrayList<*>.processXmlData(tagName: String): T? { val textContent = element.firstChild.textContent return when (T::class) { - Float::class -> textContent.toFloat() as T - Double::class -> textContent.toDouble() as T - else -> textContent as T + Float::class -> { + val floatValue = textContent.toFloatOrNull() + if (floatValue != null) floatValue as T else null + } + Double::class -> { + val doubleValue = textContent.toDoubleOrNull() + if (doubleValue != null) doubleValue as T else null + } + else -> return null } } } From 02077cad7a51d377b2e67dacb6181ef6eae5afcf Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 19 Feb 2024 10:42:17 +0100 Subject: [PATCH 5/7] Add DavPropertyProcessorTest Signed-off-by: alperozturk --- .../extensions/DavPropertyProcessorTest.kt | 98 +++++++++++++++++++ .../nextcloud/extensions/ElementCreator.kt | 21 ++++ .../extensions/XmlDataProcessorTest.kt | 14 --- .../nextcloud/extensions/GsonExtensions.kt | 7 +- 4 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 library/src/androidTest/java/com/nextcloud/extensions/DavPropertyProcessorTest.kt create mode 100644 library/src/androidTest/java/com/nextcloud/extensions/ElementCreator.kt diff --git a/library/src/androidTest/java/com/nextcloud/extensions/DavPropertyProcessorTest.kt b/library/src/androidTest/java/com/nextcloud/extensions/DavPropertyProcessorTest.kt new file mode 100644 index 000000000..15da36748 --- /dev/null +++ b/library/src/androidTest/java/com/nextcloud/extensions/DavPropertyProcessorTest.kt @@ -0,0 +1,98 @@ +package com.nextcloud.extensions + +import com.google.gson.Gson +import org.apache.jackrabbit.webdav.property.DavProperty +import org.apache.jackrabbit.webdav.property.DavPropertyName +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test +import org.w3c.dom.Document +import org.w3c.dom.Element + +class DavPropertyProcessorTest { + data class TestData(val name: String, val age: Int) + + private val gson = Gson() + + @Test + fun testFromDavPropertyWhenGivenValidDataShouldReturnExpectedData() { + val result = + gson.fromDavProperty( + object : DavProperty { + override fun toXml(document: Document?): Element { + return createElement("TestData", value) + } + + override fun getName(): DavPropertyName { + return DavPropertyName.DISPLAYNAME + } + + override fun getValue(): String { + return "{\"name\":\"John\",\"age\":55}" + } + + override fun isInvisibleInAllprop(): Boolean { + return true + } + } + ) + val expected = TestData("John", 55) + assertEquals(expected, result) + } + + @Test + fun testFromDavPropertyWhenGivenValidDataAndExpectDifferentTypeShouldReturnNull() { + val result = + gson.fromDavProperty>( + object : DavProperty { + override fun toXml(document: Document?): Element { + return createElement("TestData", value) + } + + override fun getName(): DavPropertyName { + return DavPropertyName.DISPLAYNAME + } + + override fun getValue(): String { + return "{\"name\":\"John\",\"age\":55}" + } + + override fun isInvisibleInAllprop(): Boolean { + return true + } + } + ) + assertNull(result) + } + + @Test + fun testFromDavPropertyWhenGivenInvalidDataShouldReturnNull() { + val result = + gson.fromDavProperty( + object : DavProperty { + override fun toXml(document: Document?): Element { + return createElement("TestData", "") + } + + override fun getName(): DavPropertyName { + return DavPropertyName.DISPLAYNAME + } + + override fun getValue(): String? { + return null + } + + override fun isInvisibleInAllprop(): Boolean { + return true + } + } + ) + assertNull(result) + } + + @Test + fun testFromDavPropertyWhenGivenNullDataShouldReturnNull() { + val result = gson.fromDavProperty(null) + assertNull(result) + } +} diff --git a/library/src/androidTest/java/com/nextcloud/extensions/ElementCreator.kt b/library/src/androidTest/java/com/nextcloud/extensions/ElementCreator.kt new file mode 100644 index 000000000..137c4f8f1 --- /dev/null +++ b/library/src/androidTest/java/com/nextcloud/extensions/ElementCreator.kt @@ -0,0 +1,21 @@ +package com.nextcloud.extensions + +import org.w3c.dom.Element +import javax.xml.parsers.DocumentBuilderFactory + +fun createElement( + xml: String, + value: String +): Element { + val builder = + DocumentBuilderFactory.newInstance().run { + newDocumentBuilder() + } + val document = builder.newDocument() + val element = + document.createElement(xml).apply { + textContent = value + } + document.appendChild(element) + return element +} diff --git a/library/src/androidTest/java/com/nextcloud/extensions/XmlDataProcessorTest.kt b/library/src/androidTest/java/com/nextcloud/extensions/XmlDataProcessorTest.kt index aa96be24e..d2ff8127c 100644 --- a/library/src/androidTest/java/com/nextcloud/extensions/XmlDataProcessorTest.kt +++ b/library/src/androidTest/java/com/nextcloud/extensions/XmlDataProcessorTest.kt @@ -4,10 +4,8 @@ import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Test import org.w3c.dom.Element -import javax.xml.parsers.DocumentBuilderFactory class XmlDataProcessorTest { - @Test fun testProcessXmlDataWhenGivenEmptyArrayListShouldReturnNull() { val tag = "width" @@ -66,16 +64,4 @@ class XmlDataProcessorTest { val result = xmlData.processXmlData(tag) assertNull(result) } - - private fun createElement(xml: String, value: String): Element { - val builder = DocumentBuilderFactory.newInstance().run { - newDocumentBuilder() - } - val document = builder.newDocument() - val element = document.createElement(xml).apply { - textContent = value - } - document.appendChild(element) - return element - } } diff --git a/library/src/main/java/com/nextcloud/extensions/GsonExtensions.kt b/library/src/main/java/com/nextcloud/extensions/GsonExtensions.kt index 48d773ba1..d0df4823f 100644 --- a/library/src/main/java/com/nextcloud/extensions/GsonExtensions.kt +++ b/library/src/main/java/com/nextcloud/extensions/GsonExtensions.kt @@ -1,11 +1,16 @@ package com.nextcloud.extensions import com.google.gson.Gson +import com.google.gson.JsonSyntaxException import org.apache.jackrabbit.webdav.property.DavProperty inline fun Gson.fromDavProperty(davProperty: DavProperty<*>?): T? { return if (davProperty != null && davProperty.value != null) { - fromJson(davProperty.value.toString(), T::class.java) + try { + fromJson(davProperty.value.toString(), T::class.java) + } catch (e: JsonSyntaxException) { + null + } } else { null } From 7472da6172b63249bd5eaa905dd5eac88fb10415 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 19 Feb 2024 10:48:23 +0100 Subject: [PATCH 6/7] Fix code analytics Signed-off-by: alperozturk --- .../main/java/com/nextcloud/extensions/ArrayListExtensions.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt b/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt index 16851b27f..f05747800 100644 --- a/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt +++ b/library/src/main/java/com/nextcloud/extensions/ArrayListExtensions.kt @@ -2,6 +2,7 @@ package com.nextcloud.extensions import org.w3c.dom.Element +@Suppress("ReturnCount", "NestedBlockDepth") inline fun ArrayList<*>.processXmlData(tagName: String): T? { this.forEach { val element = it as? Element From 321d6cc181e81932c1247a9dca5d4341b5d875ad Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Mon, 25 Mar 2024 12:27:36 +0100 Subject: [PATCH 7/7] use e2e master Signed-off-by: tobiasKaminsky --- .drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index 5c97b452b..e4165d097 100644 --- a/.drone.yml +++ b/.drone.yml @@ -79,7 +79,7 @@ services: - su www-data -c "php /var/www/html/occ app:enable activity" - su www-data -c "git clone -b main https://github.com/nextcloud/text.git /var/www/html/apps/text/" - su www-data -c "php /var/www/html/occ app:enable text" - - su www-data -c "git clone -b artonge/feat/allow_metadata_update_for_subfolders https://github.com/nextcloud/end_to_end_encryption/ /var/www/html/apps/end_to_end_encryption/" + - su www-data -c "git clone -b master https://github.com/nextcloud/end_to_end_encryption/ /var/www/html/apps/end_to_end_encryption/" - su www-data -c "php /var/www/html/occ app:enable end_to_end_encryption" - su www-data -c "git clone -b master https://github.com/nextcloud/password_policy/ /var/www/html/apps/password_policy/" - su www-data -c "php /var/www/html/occ app:enable password_policy" @@ -213,6 +213,6 @@ trigger: - pull_request --- kind: signature -hmac: 56749c47df149cc2d3c06343c609210a310e27635ea6ccb040890ab0afbce79d +hmac: 6d69c7c3739747691580d04a781eb67cf95d2f33f8149d5ebd2cbcc30611b4f0 ...