Skip to content

Commit b004408

Browse files
committed
fix
Signed-off-by: alperozturk <alper_ozturk@proton.me>
1 parent f695bae commit b004408

6 files changed

Lines changed: 147 additions & 29 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2025 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.owncloud.android
9+
10+
import com.owncloud.android.lib.common.utils.responseFormat.ResponseFormat
11+
import com.owncloud.android.lib.common.utils.responseFormat.ResponseFormatDetector
12+
import junit.framework.TestCase.assertEquals
13+
import org.junit.Test
14+
15+
class ResponseFormatDetectorTests {
16+
17+
@Test
18+
fun testJsonDetection() {
19+
val json = """{ "name": "Alice", "age": 30 }"""
20+
assertEquals(ResponseFormat.JSON, ResponseFormatDetector.detectFormat(json))
21+
}
22+
23+
@Test
24+
fun testJsonArrayDetection() {
25+
val jsonArray = """[{"name": "Alice"}, {"name": "Bob"}]"""
26+
assertEquals(ResponseFormat.JSON, ResponseFormatDetector.detectFormat(jsonArray))
27+
}
28+
29+
@Test
30+
fun testXmlDetection() {
31+
val xml = """<person><name>Alice</name><age>30</age></person>"""
32+
assertEquals(ResponseFormat.XML, ResponseFormatDetector.detectFormat(xml))
33+
}
34+
35+
@Test
36+
fun testInvalidFormat() {
37+
val invalid = "Just a plain string"
38+
assertEquals(ResponseFormat.UNKNOWN, ResponseFormatDetector.detectFormat(invalid))
39+
}
40+
41+
@Test
42+
fun testEmptyString() {
43+
val empty = ""
44+
assertEquals(ResponseFormat.UNKNOWN, ResponseFormatDetector.detectFormat(empty))
45+
}
46+
}

library/src/androidTest/java/com/owncloud/android/ExceptionParserIT.java renamed to library/src/androidTest/java/com/owncloud/android/XMLExceptionParserIT.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import static org.junit.Assert.assertFalse;
1111
import static org.junit.Assert.assertTrue;
1212

13-
import com.owncloud.android.lib.common.operations.ExceptionParser;
13+
import com.owncloud.android.lib.common.operations.XMLExceptionParser;
1414

1515
import org.junit.Test;
1616

@@ -23,10 +23,10 @@
2323
* Created by tobi on 3/21/18.
2424
*/
2525

26-
public class ExceptionParserIT {
26+
public class XMLExceptionParserIT {
2727

2828
@Test
29-
public void testVirusException() throws IOException {
29+
public void testVirusException() {
3030
String virusException = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
3131
"<d:error xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\">\n" +
3232
" <s:exception>OCA\\DAV\\Connector\\Sabre\\Exception\\UnsupportedMediaType" +
@@ -36,59 +36,59 @@ public void testVirusException() throws IOException {
3636
"</d:error>";
3737

3838
InputStream is = new ByteArrayInputStream(virusException.getBytes());
39-
ExceptionParser xmlParser = new ExceptionParser(is);
39+
XMLExceptionParser xmlParser = new XMLExceptionParser(is);
4040

4141
assertTrue(xmlParser.isVirusException());
4242
assertFalse(xmlParser.isInvalidCharacterException());
4343
}
4444

4545
@Test
46-
public void testInvalidCharacterException() throws IOException {
46+
public void testInvalidCharacterException() {
4747
String virusException = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
4848
"<d:error xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\">\n" +
4949
" <s:exception>OC\\Connector\\Sabre\\Exception\\InvalidPath</s:exception>\n" +
5050
" <s:message>Wrong Path</s:message>\n" +
5151
"</d:error>";
5252

5353
InputStream is = new ByteArrayInputStream(virusException.getBytes());
54-
ExceptionParser xmlParser = new ExceptionParser(is);
54+
XMLExceptionParser xmlParser = new XMLExceptionParser(is);
5555

5656
assertTrue(xmlParser.isInvalidCharacterException());
5757
assertFalse(xmlParser.isVirusException());
5858
}
5959

6060
@Test
61-
public void testInvalidCharacterUploadException() throws IOException {
61+
public void testInvalidCharacterUploadException() {
6262
String virusException = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
6363
"<d:error xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\">\n" +
6464
" <s:exception>OCP\\Files\\InvalidPathException</s:exception>\n" +
6565
" <s:message>Wrong Path</s:message>\n" +
6666
"</d:error>";
6767

6868
InputStream is = new ByteArrayInputStream(virusException.getBytes());
69-
ExceptionParser xmlParser = new ExceptionParser(is);
69+
XMLExceptionParser xmlParser = new XMLExceptionParser(is);
7070

7171
assertTrue(xmlParser.isInvalidCharacterException());
7272
assertFalse(xmlParser.isVirusException());
7373
}
7474

7575
@Test
76-
public void testEmptyString() throws IOException {
76+
public void testEmptyString() {
7777
String emptyString = "";
7878

7979
InputStream is = new ByteArrayInputStream(emptyString.getBytes());
80-
ExceptionParser xmlParser = new ExceptionParser(is);
80+
XMLExceptionParser xmlParser = new XMLExceptionParser(is);
8181

8282
assertFalse(xmlParser.isVirusException());
8383
assertFalse(xmlParser.isInvalidCharacterException());
8484
}
8585

8686
@Test
87-
public void testString() throws IOException {
87+
public void testString() {
8888
String emptyString = "";
8989

9090
InputStream is = new ByteArrayInputStream(emptyString.getBytes());
91-
ExceptionParser xmlParser = new ExceptionParser(is);
91+
XMLExceptionParser xmlParser = new XMLExceptionParser(is);
9292

9393
assertFalse(xmlParser.isVirusException());
9494
assertFalse(xmlParser.isInvalidCharacterException());

library/src/main/java/com/owncloud/android/lib/common/operations/RemoteOperationResult.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
3131
import com.owncloud.android.lib.common.network.CertificateCombinedException;
3232
import com.owncloud.android.lib.common.utils.Log_OC;
33+
import com.owncloud.android.lib.common.utils.responseFormat.ResponseFormat;
34+
import com.owncloud.android.lib.common.utils.responseFormat.ResponseFormatDetector;
3335
import com.owncloud.android.lib.resources.files.CreateLocalFileException;
3436

3537
import org.apache.commons.httpclient.ConnectTimeoutException;
@@ -235,10 +237,13 @@ public RemoteOperationResult(boolean success, String bodyResponse, int httpCode)
235237
switch (httpCode) {
236238
case HttpStatus.SC_BAD_REQUEST:
237239
try {
238-
InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
239-
ExceptionParser xmlParser = new ExceptionParser(is);
240-
if (xmlParser.isInvalidCharacterException()) {
241-
mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER;
240+
if (!bodyResponse.isEmpty() &&
241+
ResponseFormatDetector.INSTANCE.detectFormat(bodyResponse) == ResponseFormat.XML) {
242+
InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
243+
XMLExceptionParser xmlParser = new XMLExceptionParser(is);
244+
if (xmlParser.isInvalidCharacterException()) {
245+
mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER;
246+
}
242247
}
243248
} catch (Exception e) {
244249
mCode = ResultCode.UNHANDLED_HTTP_CODE;
@@ -336,9 +341,11 @@ public RemoteOperationResult(boolean success, HttpMethod httpMethod) {
336341
try {
337342
String bodyResponse = httpMethod.getResponseBodyAsString();
338343

339-
if (bodyResponse != null && bodyResponse.length() > 0) {
344+
if (bodyResponse != null
345+
&& !bodyResponse.isEmpty() &&
346+
ResponseFormatDetector.INSTANCE.detectFormat(bodyResponse) == ResponseFormat.XML) {
340347
InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
341-
ExceptionParser xmlParser = new ExceptionParser(is);
348+
XMLExceptionParser xmlParser = new XMLExceptionParser(is);
342349

343350
if (xmlParser.isInvalidCharacterException()) {
344351
mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER;

library/src/main/java/com/owncloud/android/lib/common/operations/ExceptionParser.java renamed to library/src/main/java/com/owncloud/android/lib/common/operations/XMLExceptionParser.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
*
2525
* @author masensio, tobiaskaminsky
2626
*/
27-
public class ExceptionParser {
28-
private static final String TAG = ExceptionParser.class.getSimpleName();
27+
public class XMLExceptionParser {
28+
private static final String TAG = XMLExceptionParser.class.getSimpleName();
2929

3030
private static final String INVALID_PATH_EXCEPTION_STRING = "OC\\Connector\\Sabre\\Exception\\InvalidPath";
3131
private static final String INVALID_PATH_EXCEPTION_UPLOAD_STRING = "OCP\\Files\\InvalidPathException";
@@ -46,25 +46,20 @@ public class ExceptionParser {
4646
/**
4747
* Parse is as an Invalid Path Exception
4848
*
49-
* @param is InputStream xml
50-
* @return if The exception is an Invalid Char Exception
51-
* @throws IOException
49+
* @param inputStream InputStream xml
5250
*/
53-
public ExceptionParser(InputStream is) throws IOException {
54-
try {
55-
// XMLPullParser
51+
public XMLExceptionParser(InputStream inputStream) {
52+
try (inputStream) {
5653
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
5754
factory.setNamespaceAware(true);
5855

5956
XmlPullParser parser = Xml.newPullParser();
6057
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
61-
parser.setInput(is, null);
58+
parser.setInput(inputStream, null);
6259
parser.nextTag();
6360
readError(parser);
6461
} catch (Exception e) {
6562
Log_OC.e(TAG, "Error parsing exception: " + e.getMessage());
66-
} finally {
67-
is.close();
6863
}
6964
}
7065

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2025 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.owncloud.android.lib.common.utils.responseFormat
9+
10+
enum class ResponseFormat {
11+
JSON, XML, UNKNOWN
12+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2025 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.owncloud.android.lib.common.utils.responseFormat
9+
10+
import com.owncloud.android.lib.common.utils.Log_OC
11+
import org.json.JSONArray
12+
import org.json.JSONObject
13+
import java.io.ByteArrayInputStream
14+
import javax.xml.parsers.DocumentBuilderFactory
15+
16+
object ResponseFormatDetector {
17+
private const val TAG = "ResponseFormatDetector"
18+
private const val JSON_OBJECT_PREFIX = "{"
19+
private const val JSON_ARRAY_PREFIX = "["
20+
21+
fun detectFormat(input: String): ResponseFormat {
22+
return when {
23+
isJson(input) -> ResponseFormat.JSON
24+
isXml(input) -> ResponseFormat.XML
25+
else -> ResponseFormat.UNKNOWN
26+
}
27+
}
28+
29+
private fun isJson(input: String): Boolean {
30+
return try {
31+
val trimmed = input.trim()
32+
if (trimmed.startsWith(JSON_OBJECT_PREFIX)) {
33+
JSONObject(trimmed)
34+
} else if (trimmed.startsWith(JSON_ARRAY_PREFIX)) {
35+
JSONArray(trimmed)
36+
} else {
37+
return false
38+
}
39+
true
40+
} catch (e: Exception) {
41+
Log_OC.e(TAG, "Exception isJson: $e")
42+
false
43+
}
44+
}
45+
46+
private fun isXml(input: String): Boolean {
47+
return try {
48+
val factory = DocumentBuilderFactory.newInstance()
49+
val builder = factory.newDocumentBuilder()
50+
val stream = ByteArrayInputStream(input.toByteArray())
51+
builder.parse(stream)
52+
true
53+
} catch (e: Exception) {
54+
Log_OC.e(TAG, "Exception isXml: $e")
55+
false
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)