[BUG] Uyghur translation: broken placeholders (% 1 $ s) make String.format throw (file list footer, drawer quota)
Maintainer thường phản hồi trong vòng 2 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 65/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Lĩnh vực
- localization, mobile
Hướng nghiên cứu
Các chuỗi bị lỗi nằm trong owncloudApp/src/main/res/values-ug/strings.xml (55 khóa, được liệt kê trong issue) và values-sv/strings.xml cho media_notif_ticker. Bắt đầu với FileListAdapter.kt (file_list__footer__files) và DrawerActivity.kt (drawer_quota) để xem cách các chuỗi được định dạng. Hoàn thành khi mỗi chuỗi đã dịch giữ nguyên chính xác các placeholder tiếng Anh (%1$s, %1$d, %s) và các tệp tiếng Uyghur và tiếng Thụy Điển được định dạng không có ngoại lệ. Issue cho biết phần sửa nên thực hiện trên Transifex, vì vậy hãy hỏi ý kiến người bảo trì trước khi sửa trực tiếp kho mã.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.ktcallscontext.getString(R.string.file_list__footer__files, filesCount). The Uyghur text is% 1 $ d ھۆججەتلەر. Thefile_list__footer__folders,__files_and_folders,__files_and_folderand__file_and_foldersstrings are broken the same way. - Drawer quota:
DrawerActivity.ktrunsString.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:
- Set the device language to Uyghur (ئۇيغۇرچە).
- Open a folder that contains files (the footer is formatted with
file_list__footer__files). - 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.
- Ngôn ngữ chính
- Kotlin
- Star
- 4.2k
- Fork
- 3.1k
- Merge trung bình
- 4 ngày 2 giờ
- Pull request đã merge (30 ngày)
- 17
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của owncloud/android
-
Feature request KW-related
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 2 ngày
-
KW-related Type:bug UI / UX
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 2 ngày
-
[BUG] Lint reports an errorĐang mởType:bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
owncloud/android#4485 · 6 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Contributions are welcome p3-medium Type:bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
owncloud/android#4300 · 5 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
owncloud/android#3720 · 8 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của owncloud/android
Issue tương tự
-
Good first issue: add kotlin-spring-boot stack budget preset (Kotlin + Spring Boot 3 + Gradle)Đang mởenhancement good first issue help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
bug core p3
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
RunanywhereAI/runanywhere-sdks#1083 ·
Maintainer thường phản hồi trong vòng 5 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
SLNE-Development/surf-chat#134 ·