Skip to content

Commit 788bb1d

Browse files
authored
android: handle null query results in ShareActivity (#567)
If contentResolver.query returns null, or the URI is invalid, skip processing and log instead of crashing. Also, use 'use' for the cursor instead of 'let' to automatically close the cursor after processing. Fixes tailscale/corp#24293 Signed-off-by: kari-ts <[email protected]>
1 parent c56420b commit 788bb1d

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

android/src/main/java/com/tailscale/ipn/ShareActivity.kt

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -92,38 +92,37 @@ class ShareActivity : ComponentActivity() {
9292
}
9393
}
9494

95-
val pendingFiles: List<Ipn.OutgoingFile> =
96-
uris?.filterNotNull()?.mapNotNull {
97-
contentResolver?.query(it, null, null, null, null)?.let { c ->
98-
val nameCol = c.getColumnIndex(OpenableColumns.DISPLAY_NAME)
99-
val sizeCol = c.getColumnIndex(OpenableColumns.SIZE)
100-
c.moveToFirst()
101-
val name: String =
102-
c.getString(nameCol)
103-
?: run {
104-
// For some reason, some content resolvers don't return a name.
105-
// Try to build a name from a random integer plus file extension
106-
// (if type can be determined), else just a random integer.
107-
val rand = Random.nextLong()
108-
contentResolver.getType(it)?.let { mimeType ->
109-
MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType)?.let {
110-
extension ->
111-
"$rand.$extension"
112-
} ?: "$rand"
113-
} ?: "$rand"
95+
val pendingFiles: List<Ipn.OutgoingFile> =
96+
uris?.filterNotNull()?.mapNotNull { uri ->
97+
contentResolver?.query(uri, null, null, null, null)?.use { cursor ->
98+
val nameCol = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
99+
val sizeCol = cursor.getColumnIndex(OpenableColumns.SIZE)
100+
101+
if (cursor.moveToFirst()) {
102+
val name: String = cursor.getString(nameCol)
103+
?: generateFallbackName(uri)
104+
val size: Long = cursor.getLong(sizeCol)
105+
Ipn.OutgoingFile(Name = name, DeclaredSize = size).apply {
106+
this.uri = uri
114107
}
115-
val size = c.getLong(sizeCol)
116-
c.close()
117-
val file = Ipn.OutgoingFile(Name = name, DeclaredSize = size)
118-
file.uri = it
119-
file
120-
}
121-
} ?: emptyList()
108+
} else {
109+
TSLog.e(TAG, "Cursor is empty for URI: $uri")
110+
null
111+
}
112+
}
113+
} ?: emptyList()
122114

123115
if (pendingFiles.isEmpty()) {
124116
TSLog.e(TAG, "Share failure - no files extracted from intent")
125117
}
126118

127119
requestedTransfers.set(pendingFiles)
128120
}
121+
122+
private fun generateFallbackName(uri: Uri): String {
123+
val randomId = Random.nextLong()
124+
val mimeType = contentResolver?.getType(uri)
125+
val extension = mimeType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(it) }
126+
return if (extension != null) "$randomId.$extension" else randomId.toString()
127+
}
129128
}

0 commit comments

Comments
 (0)