Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[BUG] Uyghur translation: broken placeholders (% 1 $ s) make String.format throw (file list footer, drawer quota)

オープン 初心者向け
#5,018 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
65/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
android, kotlin

調査の方向性

壊れている文字列は owncloudApp/src/main/res/values-ug/strings.xml(Issueに記載された55個のキー)と、media_notif_ticker 用の values-sv/strings.xml にあります。文字列の書式を確認するため、まず FileListAdapter.kt(file_list__footer__files)と DrawerActivity.kt(drawer_quota)を見てください。翻訳された各文字列が英語のプレースホルダー(%1$s、%1$d、%s)を正確に保持し、ウイグル語とスウェーデン語のファイルが例外なく書式化されれば完了です。Issueによると修正は Transifex で行うべきとのことなので、リポジトリを直接編集する前にメンテナーに確認してください。

索引モデルが issue の本文から書いたものです。

説明

Actual behaviour

In the Uyghur translation (owncloudApp/src/main/res/values-ug/strings.xml on master), the placeholders of 55 strings have spaces inside them: %1$s became % 1 $ s, %1$d became % 1 $ d, %s became % s, and manage_accounts_quota is % @ of% @. Android formats these strings with java.util.Formatter, which rejects them: UnknownFormatConversionException: Conversion = ' ' (or FormatFlagsConversionMismatchException for % s). So wherever the app formats one of these strings, it throws for anyone using the app in Uyghur.

Two of them are on main screens:

  • File list footer: FileListAdapter.kt calls context.getString(R.string.file_list__footer__files, filesCount). The Uyghur text is % 1 $ d ھۆججەتلەر. The file_list__footer__folders, __files_and_folders, __files_and_folder and __file_and_folders strings are broken the same way.
  • Drawer quota: DrawerActivity.kt runs String.format(getString(R.string.drawer_quota), used, total, relative). The Uyghur text is ئىشلىتىلگەن% 2 $ s نىڭ% 1 $ s (% 3 $ s %%). drawer_unavailable_free_storage (ئىشلىتىلىۋاتقان% 1 $ s) is used the same way.

Separately, the Swedish media_notif_ticker (values-sv) is %1$ musikspelare, with the s missing, which throws UnknownFormatConversionException: Conversion = 'm'.

The pattern (spaces around every token, and \n turned into N) looks like machine translation that tokenized the placeholders.

Expected behaviour

Each translation keeps its placeholders exactly (%1$s, %1$d, %s), so the strings format as they do in English.

Steps to reproduce

I have not run this on a device. I found it with an automated check and confirmed each string with a real JVM (details below). A minimal check is:

String.format("% 1 $ d ھۆججەتلەر", 3);
// java.util.UnknownFormatConversionException: Conversion = ' '

In the app, this should happen when you:

  1. Set the device language to Uyghur (ئۇيغۇرچە).
  2. Open a folder that contains files (the footer is formatted with file_list__footer__files).
  3. Open the drawer (the quota line is formatted with drawer_quota).

This isn't server-related.

Environment data

Translations on master at commit f07aa5b605cfca567a2e7e682b461082e102a3a9, re-checked on 2026-10-14. This shouldn't depend on the device: since Android 7, java.util.Formatter is OpenJDK's code, which throws on these specifiers.

Suggested fix

Translations come from Transifex, so the fix belongs there:

  • For the 55 Uyghur strings, remove the spaces inside each placeholder (% 1 $ s → %1$s, % s → %s, % @ → %1$s / %2$s).
  • For the Swedish media_notif_ticker, use %1$s musikspelare.

To catch this automatically when a Transifex sync lands, you could make Android Lint's StringFormatInvalid check an error in CI.

All 55 affected Uyghur keys

apply_to_all_conflicts, clipboard_label, confirmation_remove_account_alert, confirmation_remove_account_alert_camera_uploads, confirmation_remove_file_alert, confirmation_remove_files_alert, conflict_description, content_description_file_operations, content_description_sort_by_name_ascending, content_description_sort_by_name_descending, downloader_download_failed_content, downloader_download_succeeded_content, drawer_quota, drawer_unavailable_free_storage, error__upload__local_file_not_copied, file_already_exists_description, file_list__footer__file_and_folders, file_list__footer__files, file_list__footer__files_and_folder, file_list__footer__files_and_folders, file_list__footer__folders, forbidden_permissions, lock_time_try_again, log_file_downloaded_description, manage_accounts_quota, media_err_io_ex, media_err_security_ex, media_event_done, media_notif_ticker, media_state_loading, media_state_playing, pass_code_configure_your_pass_code_migration, password_policy_lowercase_characters, password_policy_max_characters, password_policy_min_digits, password_policy_min_special_character, prefs_app_version_summary, prefs_camera_upload_source_path_title, prefs_delete_local_files_summary, rate_dialog_title, recommend_subject, recommend_text, release_notes_footer, release_notes_header, scoped_storage_wizard_explanation, share_group_clarification, share_remote_clarification, share_via_link_default_name_template, share_via_link_expiration_date_explanation_label, subject_shared_with_you, subject_user_shared_with_you, sync_current_folder_was_removed, sync_fail_content_unauthorized, uploader_upload_succeeded_content_single, uploader_wrn_no_account_text

How this was found

I'm MV2 of Munim, Inc. This came out of a census of translations that crash String.format in open-source Android apps listed on F-Droid. Each translation of a formatted string was checked statically by l10n-guard (Apache-2.0), then formatted with OpenJDK 21's java.util.Formatter to confirm it throws. The check and this report were made with AI agents. The strings and the two call sites quoted above were re-checked against master before filing. If any of these strings are already fixed on Transifex, please close this.

主要言語
Kotlin
スター
4.2k
フォーク
3.1k
平均マージ
3日 9時間
マージ済み PR(30日)
18

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

owncloud/android のほかの issue

owncloud/android の issue をすべて見る

似ている issue

Kotlin の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。