Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 105 additions & 75 deletions crowdin/src/main/java/com/crowdin/platform/CrowdinResources.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,77 +43,94 @@ internal class CrowdinResources(
) {
@Throws(NotFoundException::class)
override fun getString(id: Int): String {
val entryName = getResourceEntryName(id)
val string = getStringFromRepository(id)?.replaceNewLine() ?: res.getString(id)
saveStringDataToCopy(entryName, string)

return string
return try {
val entryName = getResourceEntryName(id)
val string = getStringFromRepository(id)?.replaceNewLine() ?: res.getString(id)
saveStringDataToCopy(entryName, string)
string
} catch (_: NotFoundException) {
super.getString(id)
}
}

@Throws(NotFoundException::class)
override fun getString(
id: Int,
vararg formatArgs: Any,
): String {
val entryName = getResourceEntryName(id)
val string = getStringFromRepository(id)?.replaceNewLine()
val formattedString =
if (string == null) {
res.getString(id, *formatArgs)
} else {
try {
String.format(string, *formatArgs)
} catch (_: Exception) {
return try {
val entryName = getResourceEntryName(id)
val string = getStringFromRepository(id)?.replaceNewLine()
val formattedString =
if (string == null) {
res.getString(id, *formatArgs)
} else {
try {
String.format(string, *formatArgs)
} catch (_: Exception) {
res.getString(id, *formatArgs)
}
}
}

saveStringDataToCopy(entryName, formattedString, formatArgs)

return formattedString
saveStringDataToCopy(entryName, formattedString, formatArgs)
formattedString
} catch (_: NotFoundException) {
super.getString(id, *formatArgs)
}
}

@Throws(NotFoundException::class)
override fun getStringArray(id: Int): Array<String> {
val entryName = getResourceEntryName(id)
val stringArray = getStringArrayFromRepository(id) ?: res.getStringArray(id)
saveStringArrayDataToCopy(entryName, stringArray)

return stringArray
return try {
val entryName = getResourceEntryName(id)
val stringArray = getStringArrayFromRepository(id) ?: res.getStringArray(id)
saveStringArrayDataToCopy(entryName, stringArray)
stringArray
} catch (_: NotFoundException) {
super.getStringArray(id)
}
}

@Throws(NotFoundException::class)
override fun getText(id: Int): CharSequence {
val entryName = getResourceEntryName(id)
val string = getStringFromRepository(id)
val formattedString = string?.fromHtml() ?: res.getText(id)
saveStringDataToCopy(entryName, formattedString.toString())

return formattedString
return try {
val entryName = getResourceEntryName(id)
val string = getStringFromRepository(id)
val formattedString = string?.fromHtml() ?: res.getText(id)
saveStringDataToCopy(entryName, formattedString.toString())
formattedString
} catch (_: NotFoundException) {
super.getText(id)
}
}

override fun getText(
id: Int,
default: CharSequence,
): CharSequence {
val entryName = getResourceEntryName(id)
val string = getStringFromRepository(id)
val formattedString = string?.fromHtml() ?: res.getText(id, default)
saveStringDataToCopy(entryName, formattedString.toString(), default = default)

return formattedString
return try {
val entryName = getResourceEntryName(id)
val string = getStringFromRepository(id)
val formattedString = string?.fromHtml() ?: res.getText(id, default)
saveStringDataToCopy(entryName, formattedString.toString(), default = default)
formattedString
} catch (_: NotFoundException) {
super.getText(id, default)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quantity methods lack NotFoundException catch unlike other overrides

Medium Severity

The getQuantityText and getQuantityString methods lack the try-catch (NotFoundException) wrapper present in other Resources overrides. While their internal helpers now safely return null for non-app IDs, the fallback calls to the base res.getQuantityText or res.getQuantityString can still throw NotFoundException, causing crashes.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 37e557a. Configure here.

}

@Throws(NotFoundException::class)
override fun getQuantityText(
id: Int,
quantity: Int,
): CharSequence {
val plural = getPluralFromRepository(id, quantity)
val formattedPlural = plural?.fromHtml() ?: res.getQuantityText(id, quantity)
savePluralToCopy(id, quantity, formattedPlural.toString())

return formattedPlural
return try {
val plural = getPluralFromRepository(id, quantity)
val formattedPlural = plural?.fromHtml() ?: res.getQuantityText(id, quantity)
savePluralToCopy(id, quantity, formattedPlural.toString())
formattedPlural
} catch (_: NotFoundException) {
super.getQuantityText(id, quantity)
}
}

@Throws(NotFoundException::class)
Expand All @@ -122,21 +139,23 @@ internal class CrowdinResources(
quantity: Int,
vararg formatArgs: Any?,
): String {
val plural = getPluralFromRepository(id, quantity)
val formattedPlural =
if (plural == null) {
res.getQuantityString(id, quantity, *formatArgs)
} else {
try {
String.format(plural, *formatArgs)
} catch (ex: Exception) {
return try {
val plural = getPluralFromRepository(id, quantity)
val formattedPlural =
if (plural == null) {
res.getQuantityString(id, quantity, *formatArgs)
} else {
try {
String.format(plural, *formatArgs)
} catch (_: Exception) {
res.getQuantityString(id, quantity, *formatArgs)
}
}
}

savePluralToCopy(id, quantity, formattedPlural, formatArgs)

return formattedPlural
savePluralToCopy(id, quantity, formattedPlural, formatArgs)
formattedPlural
} catch (_: NotFoundException) {
super.getQuantityString(id, quantity, *formatArgs)
}
}

@RequiresApi(Build.VERSION_CODES.R)
Expand Down Expand Up @@ -223,12 +242,14 @@ internal class CrowdinResources(
id: Int,
quantity: Int,
): String {
val plural = getPluralFromRepository(id, quantity)
val formattedPlural = plural ?: res.getQuantityString(id, quantity)

savePluralToCopy(id, quantity, formattedPlural)

return formattedPlural
return try {
val plural = getPluralFromRepository(id, quantity)
val formattedPlural = plural ?: res.getQuantityString(id, quantity)
savePluralToCopy(id, quantity, formattedPlural)
formattedPlural
} catch (_: NotFoundException) {
super.getQuantityString(id, quantity)
}
}

override fun toString(): String = res.toString()
Expand Down Expand Up @@ -356,7 +377,11 @@ internal class CrowdinResources(
defaultText: String,
formatArgs: Array<out Any?> = arrayOf(),
) {
val entryName = getResourceEntryName(id)
val entryName = try {
getResourceEntryName(id)
} catch (_: NotFoundException) {
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val rule = PluralRules.forLocale(configuration.getLocale())
val ruleName = rule.select(quantity.toDouble())
Expand All @@ -383,24 +408,29 @@ internal class CrowdinResources(
}

private fun getStringArrayFromRepository(id: Int): Array<String>? {
val entryName = getResourceEntryName(id)
val localeCode = configuration.getLocale().getFormattedCode()

return dataManager.getStringArray(localeCode, entryName)
return try {
val entryName = getResourceEntryName(id)
val localeCode = configuration.getLocale().getFormattedCode()
dataManager.getStringArray(localeCode, entryName)
} catch (_: NotFoundException) {
null
}
}

private fun getPluralFromRepository(
id: Int,
quantity: Int,
): String? =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val locale = configuration.getLocale()
val localeCode = locale.getFormattedCode()
val entryName = getResourceEntryName(id)
val rule = PluralRules.forLocale(locale)
val ruleName = rule.select(quantity.toDouble())
dataManager.getStringPlural(localeCode, entryName, ruleName)
} else {
null
): String? {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) return null
val locale = configuration.getLocale()
val localeCode = locale.getFormattedCode()
val entryName = try {
getResourceEntryName(id)
} catch (_: NotFoundException) {
return null
}
val rule = PluralRules.forLocale(locale)
val ruleName = rule.select(quantity.toDouble())
return dataManager.getStringPlural(localeCode, entryName, ruleName)
}
}
Loading