Compare commits

..

4 Commits

Author SHA1 Message Date
Wang Han
ecc4e1b7b2 Update resetprop to support --compact 2026-03-14 19:27:09 +08:00
Neebe3289
1d4fbd9e75 Update Indonesian translation
Change-Id: I19f109e9cdfec643b33180a78b932f47b2030d7d
2026-03-11 00:45:08 -07:00
yashikada
7845da2943 Workaround for #9726 2026-03-11 00:44:18 -07:00
topjohnwu
6bb48df712 Go through rustup proxy if possible 2026-03-11 00:43:18 -07:00
18 changed files with 836 additions and 149 deletions

3
.gitmodules vendored
View File

@@ -1,6 +1,9 @@
[submodule "selinux"]
path = native/src/external/selinux
url = https://github.com/topjohnwu/selinux.git
[submodule "lz4"]
path = native/src/external/lz4
url = https://github.com/lz4/lz4.git
[submodule "libcxx"]
path = native/src/external/libcxx
url = https://github.com/topjohnwu/libcxx.git

View File

@@ -123,7 +123,7 @@ interface LocaleSetting {
names.add(AppContext.getString(R.string.system_default))
tags.add("")
if (Build.VERSION.SDK_INT >= 34) {
if ((Build.VERSION.SDK_INT == 34 && !isRunningAsStub) || Build.VERSION.SDK_INT >= 35) {
// Use platform LocaleConfig parser
val config = localeConfig
val list = config.supportedLocales ?: LocaleList.getEmptyLocaleList()
@@ -168,7 +168,7 @@ interface LocaleSetting {
}
private val localeManagerUsable get() =
if (isRunningAsStub) Build.VERSION.SDK_INT >= 34 else Build.VERSION.SDK_INT >= 33
if (isRunningAsStub) Build.VERSION.SDK_INT >= 35 else Build.VERSION.SDK_INT >= 33
val useLocaleManager by lazy {
localeManagerUsable &&

View File

@@ -19,17 +19,16 @@
<string name="hide">Tutup</string>
<string name="home_package">Paket</string>
<string name="home_app_title">Aplikasi</string>
<string name="home_notice_content">Unduh Magisk HANYA dari halaman GitHub resmi kami. File dari sumber yang tidak dikenal dapat berbahaya!</string>
<string name="home_support_title">Dukung kami</string>
<string name="home_notice_content">Unduh Magisk HANYA dari halaman GitHub resmi. Berkas dari sumber yang tidak dikenal dapat berbahaya!</string>
<string name="home_support_title">Dukung Kami</string>
<string name="home_follow_title">Ikuti Kami</string>
<string name="home_item_source">Sumber</string>
<string name="home_support_content">Magisk gratis dan bersumber terbuka, dan akan selalu seperti itu. Bagaimanapun juga Anda dapat menunjukan kepedulian Anda kepada kami dengan mengirimkan sedikit donasi.</string>
<string name="home_support_content">Magisk akan selalu menjadi aplikasi gratis dan serta bersumber terbuka. Bagaimanapun juga, Anda dapat menunjukan kepedulian Anda kepada kami dengan memberikan sedikit donasi.</string>
<string name="home_installed_version">Terpasang</string>
<string name="home_latest_version">Terbaru</string>
<string name="invalid_update_channel">Saluran pembaruan tidak valid</string>
<string name="uninstall_magisk_title">Copot Magisk</string>
<string name="uninstall_magisk_msg">Semua modul akan dinonaktifkan/dihapus!\nRoot akan dihapus!\nData Anda berpotensi terenkripsi jika belum!</string>
<string name="uninstall_magisk_title">Hapus Magisk</string>
<string name="uninstall_magisk_msg">Semua modul akan dinonaktifkan/dihapus!\nRoot akan dihapus!\nSemua data internal yang tidak dienkripsi melalui penggunaan Magisk akan dienkripsi ulang!</string>
<!--Install-->
<string name="keep_force_encryption">Pertahankan enkripsi paksa</string>
@@ -39,118 +38,122 @@
<string name="install_method_title">Metode</string>
<string name="install_next">Berikutnya</string>
<string name="install_start">Mulai</string>
<string name="manager_download_install">Sentuh untuk unduh dan pasang</string>
<string name="manager_download_install">Sentuh untuk mengunduh dan memasang</string>
<string name="direct_install">Langsung pasang (Disarankan)</string>
<string name="install_inactive_slot">Pasang pada slot nonaktif (Setelah OTA)</string>
<string name="install_inactive_slot_msg">Perangkat Anda akan DIPAKSA boot ke slot yang saat ini tidak aktif setelah perangkat dinyalakan ulang!\nGunakan opsi ini hanya setelah proses OTA selesai.\nLanjutkan?</string>
<string name="install_inactive_slot">Pasang ke slot nonaktif (Setelah OTA)</string>
<string name="install_inactive_slot_msg">Perangkat Anda akan DIPAKSA untuk boot ke slot nonaktif saat ini setelah dimulai ulang!\nGunakan opsi ini hanya setelah OTA selesai.\nLanjutkan?</string>
<string name="setup_title">Penyiapan tambahan</string>
<string name="select_patch_file">Pilih dan tambal file</string>
<string name="patch_file_msg">Pilih mentahan image (*.img) atau file tar ODIN (*.tar)</string>
<string name="select_patch_file">Pilih dan tambal berkas</string>
<string name="patch_file_msg">Pilih mentahan image (*.img) atau berkas tar ODIN (*.tar) atau payload.bin (*.bin)</string>
<string name="reboot_delay_toast">Memulai ulang dalam 5 detik…</string>
<string name="flash_screen_title">Instalasi</string>
<string name="flash_screen_title">Memasang</string>
<!--Superuser-->
<string name="su_request_title">Permintaan superuser</string>
<string name="touch_filtered_warning">Karena terdapat aplikasi yang menghalangi dialog permintaan superuser, Magisk tidak dapat memverifikasi respons Anda</string>
<string name="su_request_title">Permintaan Superuser</string>
<string name="touch_filtered_warning">Magisk tidak dapat memverifikasi respons Anda, karena ada aplikasi yang menutupi permintaan superuser.</string>
<string name="deny">Tolak</string>
<string name="prompt">Ajukan</string>
<string name="restrict">Batasi</string>
<string name="grant">Izinkan</string>
<string name="su_warning">Berikan akses penuh ke perangkat Anda.\nTolak jika Anda tidak yakin!</string>
<string name="forever">Selamanya</string>
<string name="once">Sekali</string>
<string name="tenmin">10 mnt</string>
<string name="twentymin">20 mnt</string>
<string name="thirtymin">30 mnt</string>
<string name="sixtymin">60 mnt</string>
<string name="su_allow_toast">%1$s mendapatkan hak superuser</string>
<string name="su_deny_toast">%1$s ditolak atas hak superuser</string>
<string name="su_snack_grant">Hak superuser %1$s diberikan</string>
<string name="su_snack_deny">Hak superuser %1$s ditolak</string>
<string name="su_snack_notif_on">Notifikasi %1$s diaktifkan</string>
<string name="su_snack_notif_off">Notifikasi %1$s dinonaktifkan</string>
<string name="tenmin">10 menit</string>
<string name="twentymin">20 menit</string>
<string name="thirtymin">30 menit</string>
<string name="sixtymin">60 menit</string>
<string name="su_allow_toast">%1$s diberikan izin superuser</string>
<string name="su_deny_toast">%1$s ditolak izin superuser</string>
<string name="su_snack_grant">Izin superuser %1$s diberikan</string>
<string name="su_snack_deny">Izin superuser %1$s ditolak</string>
<string name="su_snack_notif_on">Notifikasi %1$ diaktifkan</string>
<string name="su_snack_notif_off">Notifikasi %1$ dinonaktifkan</string>
<string name="su_snack_log_on">Pencatatan log %1$s diaktifkan</string>
<string name="su_snack_log_off">Pencatatan log %1$s dinonaktifkan</string>
<string name="su_revoke_title">Cabut?</string>
<string name="su_revoke_msg">Konfirmasi untuk mencabut hak %1$s?</string>
<string name="toast">Toast</string>
<string name="su_revoke_msg">Konfirmasi untuk mencabut izin %1$s</string>
<string name="toast">Pesan singkat</string>
<string name="none">Tidak ada</string>
<string name="superuser_toggle_notification">Notifikasi</string>
<string name="superuser_toggle_revoke">Cabut</string>
<string name="superuser_policy_none">Belum ada aplikasi yang meminta izin superuser.</string>
<!--Logs-->
<string name="log_data_none">Log Anda masih kosong, coba gunakan lebih banyak aplikasi yang membutuhkan SU Anda</string>
<string name="log_data_magisk_none">Log Magisk kosong, ini aneh</string>
<string name="log_data_none">Belum ada log. Coba gunakan aplikasi root Anda lebih sering.</string>
<string name="log_data_magisk_none">Log Magisk kosong, ini aneh.</string>
<string name="menuSaveLog">Simpan log</string>
<string name="menuClearLog">Hapus log sekarang</string>
<string name="logs_cleared">Log berhasil dihapus</string>
<string name="menuClearLog">Bersihkan log</string>
<string name="logs_cleared">Log berhasil dibersihkan</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">Target UID: %1$d</string>
<!--SafetyNet-->
<string name="target_uid">UID Target: %1$d</string>
<string name="target_pid">PID Target: %s</string>
<string name="selinux_context">Konteks SELinux: %s</string>
<string name="supp_group">Grup tambahan: %s</string>
<!--MagiskHide-->
<string name="show_system_app">Tampilkan aplikasi sistem</string>
<string name="show_os_app">Tampilkan aplikasi OS</string>
<string name="hide_filter_hint">Filter menurut nama</string>
<string name="hide_filter_hint">Saring berdasarkan nama</string>
<string name="hide_search">Telusuri</string>
<!--Module-->
<string name="no_info_provided">(Info tidak tersedia)</string>
<string name="reboot_userspace">Mulai ulang secara halus</string>
<string name="reboot_recovery">Mulai ulang ke mode Recovery</string>
<string name="reboot_bootloader">Mulai ulang ke mode Bootloader</string>
<string name="reboot_download">Mulai ulang ke mode Download</string>
<string name="reboot_edl">Mulai ulang ke mode EDL</string>
<string name="reboot_recovery">Mulai ulang ke Recovery</string>
<string name="reboot_bootloader">Mulai ulang ke Bootloader</string>
<string name="reboot_download">Mulai ulang ke Download</string>
<string name="reboot_edl">Mulai ulang ke EDL</string>
<string name="reboot_safe_mode">Mode aman</string>
<string name="module_version_author">%1$s oleh %2$s</string>
<string name="module_state_remove">Hapus</string>
<string name="module_action">Tindakan</string>
<string name="module_state_restore">Pulihkan</string>
<string name="module_action_install_external">Pasang dari penyimpanan</string>
<string name="update_available">Pembaruan tersedia</string>
<string name="suspend_text_riru">Modul ditangguhkan karena %1$s diaktifkan</string>
<string name="suspend_text_zygisk">Modul ditangguhkan karena %1$s tidak diaktifkan</string>
<string name="zygisk_module_unloaded">Modul Zygisk tidak dimuat karena ketidakcocokan</string>
<string name="zygisk_module_unloaded">Modul Zygisk tidak dimuat karena tidak kompatibel</string>
<string name="module_empty">Tidak ada modul terpasang</string>
<string name="confirm_install">Pasang modul %1$s?</string>
<string name="confirm_install_title">Konfirmasi Pasang</string>
<string name="confirm_install_title">Konfirmasi pemasangan</string>
<!--Settings-->
<string name="settings_dark_mode_title">Mode tema</string>
<string name="settings_dark_mode_message">Pilih mode yang paling cocok dengan gaya Anda!</string>
<string name="settings_dark_mode_message">Pilih mode yang paling sesuai dengan gaya Anda!</string>
<string name="settings_dark_mode_light">Selalu terang</string>
<string name="settings_dark_mode_system">Ikuti sistem</string>
<string name="settings_dark_mode_dark">Selalu gelap</string>
<string name="settings_download_path_title">Lokasi unduhan</string>
<string name="settings_download_path_message">File akan disimpan ke %1$s</string>
<string name="settings_download_path_message">Berkas akan disimpan ke %1$s</string>
<string name="settings_hide_app_title">Sembunyikan aplikasi Magisk</string>
<string name="settings_hide_app_summary">Pasang aplikasi proxy dengan ID paket acak dan label aplikasi khusus</string>
<string name="settings_restore_app_title">Pulihkan aplikasi Magisk</string>
<string name="settings_restore_app_summary">Tampilkan aplikasi and pulihkan APK asli</string>
<string name="settings_restore_app_summary">Tampilkan kembali aplikasi yang disembunyikan dan pulihkan APK aslinya</string>
<string name="language">Bahasa</string>
<string name="system_default">(Bawaan sistem)</string>
<string name="settings_check_update_title">Periksa pembaruan</string>
<string name="settings_check_update_summary">Periksa pembaruan secara berkala di latar belakang</string>
<string name="settings_check_update_summary">Memeriksa pembaruan secara berkala di latar belakang</string>
<string name="settings_update_channel_title">Saluran pembaruan</string>
<string name="settings_update_stable">Stabil</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Saluran khusus</string>
<string name="settings_update_custom_msg">Masukkan URL khusus</string>
<string name="settings_zygisk_summary">Jalankan bagian-bagian Magisk dalam zygote daemon</string>
<string name="settings_update_debug">Debug</string>
<string name="settings_update_custom">Khusus</string>
<string name="settings_update_custom_msg">Masukkan URL saluran khusus</string>
<string name="settings_zygisk_summary">Menjalankan sebagian komponen Magisk di daemon Zygote</string>
<string name="settings_denylist_title">Paksa DenyList</string>
<string name="settings_denylist_summary">Proses pada denylist akan mengembalikan semua modifikasi Magisk</string>
<string name="settings_denylist_config_title">Konfigurasi DenyList</string>
<string name="settings_denylist_config_summary">Pilih proses yang akan disertakan pada denylist</string>
<string name="settings_denylist_config_summary">Pilih proses yang akan disertakan ke dalam denylist</string>
<string name="settings_hosts_title">Host systemless</string>
<string name="settings_hosts_summary">Dukungan host secara systemless untuk aplikasi pemblokir iklan</string>
<string name="settings_hosts_summary">Dukungan host systemless untuk aplikasi pemblokir iklan</string>
<string name="settings_hosts_toast">Menambahkan modul host systemless</string>
<string name="settings_app_name_hint">Nama baru</string>
<string name="settings_app_name_helper">Aplikasi akan dikemas dengan nama tersebut</string>
<string name="settings_app_name_helper">Aplikasi akan dikemas ulang dengan nama tersebut</string>
<string name="settings_app_name_error">Format tidak valid</string>
<string name="settings_su_app_adb">Apl dan ADB</string>
<string name="settings_su_app">Apl saja</string>
<string name="settings_su_adb">ADB saja</string>
<string name="settings_su_disable">Nonaktif</string>
<string name="settings_su_app_adb">Aplikasi dan ADB</string>
<string name="settings_su_app">Hanya Aplikasi</string>
<string name="settings_su_adb">Hanya ADB</string>
<string name="settings_su_disable">Dinonaktifkan</string>
<string name="settings_su_request_10">10 detik</string>
<string name="settings_su_request_15">15 detik</string>
<string name="settings_su_request_20">20 detik</string>
@@ -161,39 +164,44 @@
<string name="auto_response">Respons otomatis</string>
<string name="request_timeout">Batas waktu permintaan</string>
<string name="superuser_notification">Notifikasi superuser</string>
<string name="settings_su_reauth_title">Autentikasi ulang setelah peningkatan</string>
<string name="settings_su_reauth_summary">Autentikasi ulang izin akses superuser setelah aplikasi ditingkatkan</string>
<string name="settings_su_tapjack_title">Aktifkan perlindungan tapjacking</string>
<string name="settings_su_tapjack_summary">Dialog permintaan superuser tidak akan menanggapi masukan saat terhalangi oleh lapisan atau jendela lainnya</string>
<string name="settings_su_reauth_title">Autentikasikan setelah pembaruan</string>
<string name="settings_su_reauth_summary">Minta izin akses superuser lagi setelah memperbarui aplikasi</string>
<string name="settings_su_tapjack_title">Perlindungan tapjacking</string>
<string name="settings_su_tapjack_summary">Dialog permintaan superuser tidak akan merespons input saat tertutup oleh jendela atau overlay lain</string>
<string name="settings_su_auth_title">Autentikasi pengguna</string>
<string name="settings_su_auth_summary">Minta autentikasi pengguna selama permintaan superuser</string>
<string name="settings_su_auth_insecure">Tidak ada metode autentikasi yang dikonfigurasi pada perangkat</string>
<string name="settings_su_restrict_title">Batasi kemampuan root</string>
<string name="settings_su_restrict_summary">Secara bawaan akan membatasi aplikasi superuser baru. Peringatan: dapat menyebabkan sebagian besar aplikasi tidak berfungsi. Jangan aktifkan kecuali Anda memahami risikonya.</string>
<string name="settings_customization">Personalisasi</string>
<string name="setting_add_shortcut_summary">Tambahkan pintasan yang menarik pada layar utama seandainya nama dan ikon sulit untuk dikenali setelah menyembunyikan aplikasi</string>
<string name="setting_add_shortcut_summary">Tambahkan pintasan yang menarik ke layar utama jika nama dan ikon sulit dikenali setelah menyembunyikan aplikasi</string>
<string name="settings_doh_title">DNS melalui HTTPS</string>
<string name="settings_doh_description">Solusi untuk DNS poisoning di beberapa negara</string>
<string name="settings_doh_description">Solusi mengatasi masalah DNS di beberapa negara</string>
<string name="settings_random_name_title">Acak nama output</string>
<string name="settings_random_name_description">Acak nama berkas output dari image yang dipatch dan berkas tar untuk mencegah deteksi</string>
<string name="multiuser_mode">Mode multi pengguna</string>
<string name="settings_owner_only">Pemilik perangkat saja</string>
<string name="settings_owner_manage">Pemilik perangkat mengelola</string>
<string name="settings_user_independent">Pengguna independen</string>
<string name="settings_owner_only">Hanya pemilik perangkat</string>
<string name="settings_owner_manage">Dikelola pemilik perangkat</string>
<string name="settings_user_independent">Independen per pengguna</string>
<string name="owner_only_summary">Hanya pemilik yang memiliki akses root</string>
<string name="owner_manage_summary">Hanya pemilik yang dapat mengelola akses root dan menerima pesan permintaan</string>
<string name="user_independent_summary">Setiap pengguna memiliki aturan root mereka sendiri</string>
<string name="mount_namespace_mode">Mode ruang-nama mount</string>
<string name="settings_ns_global">Ruang-nama global</string>
<string name="settings_ns_requester">Ruang-nama warisan</string>
<string name="settings_ns_isolate">Ruang-nama terpisah</string>
<string name="owner_manage_summary">Hanya pemilik yang dapat mengelola akses root dan menerima permintaan</string>
<string name="user_independent_summary">Setiap pengguna memiliki aturan root terpisah</string>
<string name="mount_namespace_mode">Ruang-nama mount</string>
<string name="settings_ns_global">Global</string>
<string name="settings_ns_requester">Diwariskan</string>
<string name="settings_ns_isolate">Terpisah</string>
<string name="global_summary">Semua sesi root menggunakan ruang-nama mount global</string>
<string name="requester_summary">Sesi root akan mewarisi ruang-nama peminta mereka</string>
<string name="requester_summary">Sesi root akan mewarisi ruang-nama dari pemintanya</string>
<string name="isolate_summary">Setiap sesi root akan memiliki ruang-nama tersendiri</string>
<!--Notifications-->
<string name="update_channel">Pembaruan Magisk</string>
<string name="progress_channel">Notifikasi Kemajuan</string>
<string name="updated_channel">Pembaruan Selesai</string>
<string name="progress_channel">Notifikasi kemajuan</string>
<string name="updated_channel">Pembaruan selesai</string>
<string name="download_complete">Unduhan selesai</string>
<string name="download_file_error">Kesalahan saat mengunduh file</string>
<string name="download_file_error">Kesalahan saat mengunduh berkas</string>
<string name="magisk_update_title">Pembaruan Magisk tersedia!</string>
<string name="updated_title">Magisk Diperbarui</string>
<string name="updated_title">Magisk diperbarui</string>
<string name="updated_text">Ketuk untuk buka aplikasi</string>
<!--Toasts, Dialogs-->
@@ -202,37 +210,41 @@
<string name="repo_install_title">Pasang %1$s %2$s(%3$d)</string>
<string name="download">Unduh</string>
<string name="reboot">Mulai ulang</string>
<string name="close">Tutup</string>
<string name="release_notes">Catatan rilis</string>
<string name="flashing">Memasang…</string>
<string name="running">Memproses…</string>
<string name="done">Selesai!</string>
<string name="done_action">Tindakan %1$s telah selesai</string>
<string name="failure">Gagal!</string>
<string name="hide_app_title">Menyembunyikan aplikasi Magisk…</string>
<string name="open_link_failed_toast">Tidak ditemukan aplikasi untuk membuka link ini</string>
<string name="complete_uninstall">Pencopotan penuh</string>
<string name="open_link_failed_toast">Tidak ditemukan aplikasi untuk membuka tautan</string>
<string name="complete_uninstall">Penghapusan penuh</string>
<string name="restore_img">Pulihkan image</string>
<string name="restore_img_msg">Memulihkan…</string>
<string name="restore_done">Pemulihan selesai!</string>
<string name="restore_fail">Cadangan stock tidak ada!</string>
<string name="restore_done">Memulihkan selesai!</string>
<string name="restore_fail">Cadangan asli tidak ada!</string>
<string name="setup_fail">Penyiapan gagal</string>
<string name="env_fix_title">Perlu penyiapan tambahan</string>
<string name="env_fix_msg">Perangkat Anda membutuhkan pengaturan tambahan untuk Magisk agar berfungsi dengan benar. Apakah Anda ingin melanjutkan dan Menyalakan ulang?</string>
<string name="env_full_fix_msg">Perangkat Anda membutuhkan pemasangan ulang Magisk agar berfungsi dengan baik. Silakan pasang ulang Magisk dalam aplikasi, mode recovery tidak dapat memperoleh info perangkat yang benar.</string>
<string name="setup_msg">Memproses penyiapan lingkungan…</string>
<string name="env_fix_msg">Perangkat Anda memerlukan penyiapan tambahan agar Magisk dapat berfungsi dengan benar. Apakah Anda ingin melanjutkan dan memulai ulang?</string>
<string name="env_full_fix_msg">Perangkat Anda perlu melakukan pemasangan ulang Magisk agar berfungsi dengan benar. Harap pasang ulang Magisk melalui aplikasi, mode recovery tidak dapat memperoleh informasi perangkat yang benar.</string>
<string name="setup_msg">Menyiapkan lingkungan…</string>
<string name="unsupport_magisk_title">Versi Magisk tidak didukung</string>
<string name="unsupport_magisk_msg">Versi aplikasi ini tidak mendukung versi Magisk yang lebih rendah dari %1$s.\n\nAplikasi akan berperilaku seolah-olah tidak ada Magisk yang dipasang, harap tingkatkan Magisk sesegera mungkin.</string>
<string name="unsupport_general_title">Keadaan tidak normal</string>
<string name="unsupport_system_app_msg">Menjalankan aplikasi ini sebagai aplikasi sistem tidak didukung. Harap kembalikan aplikasi ke aplikasi pengguna.</string>
<string name="unsupport_other_su_msg">Sebuah \"su\" biner bukan dari Magisk telah terdeteksi. Hapus semua solusi root yang bersaing dan/atau pasang ulang Magisk.</string>
<string name="unsupport_magisk_msg">Versi aplikasi ini tidak mendukung versi Magisk yang lebih rendah dari %1$s.\n\nAplikasi akan berperilaku seolah-olah tidak ada Magisk yang terpasang. Harap perbarui Magisk sesegera mungkin.</string>
<string name="unsupport_general_title">Status abnormal</string>
<string name="unsupport_system_app_msg">Menjalankan aplikasi ini sebagai aplikasi sistem tidak didukung. Harap kembalikan ke aplikasi pengguna.</string>
<string name="unsupport_other_su_msg">Sebuah biner \"su\" bukan berasal dari Magisk telah terdeteksi. Harap hapus solusi root yang bersaing dan/atau pasang ulang Magisk.</string>
<string name="unsupport_external_storage_msg">Magisk dipasang ke penyimpanan eksternal. Harap pindahkan aplikasi ke penyimpanan internal.</string>
<string name="unsupport_nonroot_stub_msg">Aplikasi Magisk yang tersembunyi tidak dapat terus berfungsi karena root hilang. Tolong pulihkan APK asli.</string>
<string name="unsupport_nonroot_stub_msg">Aplikasi Magisk tersembunyi tidak dapat berfungsi lagi karena akses root hilang. Harap pulihkan APK asli.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Berikan izin akses ke penyimpanan untuk mengaktifkan fungsi ini</string>
<string name="post_notifications_denied">Berikan izin akses ke notifikasi untuk mengaktifkan fungsi ini</string>
<string name="install_unknown_denied">Izinkan "Sumber tidak dikenal" untuk mengaktifkan fungsi ini</string>
<string name="external_rw_permission_denied">Berikan izin penyimpanan untuk mengaktifkan fungsi ini</string>
<string name="post_notifications_denied">Berikan izin notifikasi untuk mengaktifkan fungsi ini</string>
<string name="install_unknown_denied">Izinkan \"Sumber tidak dikenal\" untuk mengaktifkan fungsi ini</string>
<string name="add_shortcut_title">Tambahkan pintasan ke layar utama</string>
<string name="add_shortcut_msg">Setelah menyembunyikan aplikasi ini, nama dan ikonnya mungkin sulit dikenali. Apakah Anda ingin menambahkan pintasan cantik ke layar utama?</string>
<string name="add_shortcut_msg">Setelah menyembunyikan aplikasi ini, nama dan ikonnya mungkin sulit dikenali. Apakah Anda ingin menambahkan pintasan ke layar utama?</string>
<string name="app_not_found">Tidak ditemukan aplikasi untuk menangani tindakan ini</string>
<string name="reboot_apply_change">Mulai ulang untuk menerapkan perubahan</string>
<string name="restore_app_confirmation">Ini akan mengembalikan aplikasi tersembunyi kembali ke aplikasi asli. Apakah Anda benar-benar ingin melakukan ini?</string>
<string name="restore_app_confirmation">Ini akan mengembalikan aplikasi tersembunyi ke aslinya. Apakah Anda benar-benar ingin melakukan ini?</string>
</resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="upgrade_msg">Tingkatkan Magisk Manager ke versi utuh untuk menyelesaikan penyiapan. Download dan instal?</string>
<string name="no_internet_msg">Harap sambungkan ke Internet! Peningkatan Magisk Manager versi utuh diperlukan.</string>
<string name="dling">Mendownload</string>
<string name="relaunch_app">Buka kembali aplikasi secara manual</string>
<string name="upgrade_msg">Tingkatkan ke Magisk penuh untuk menyelesaikan penyiapan. Unduh dan pasang?</string>
<string name="no_internet_msg">Harap sambungkan ke Internet! Peningkatan ke Magisk penuh diperlukan.</string>
<string name="dling">Mengunduh</string>
<string name="relaunch_app">Silakan jalankan ulang aplikasi secara manual</string>
</resources>

View File

@@ -239,15 +239,19 @@ def build_cpp_src(targets: set[str]):
def run_cargo(cmds: list[str]):
ensure_paths()
env = os.environ.copy()
env["PATH"] = f"{rust_sysroot / "bin"}{os.pathsep}{env["PATH"]}"
env["CARGO_BUILD_RUSTFLAGS"] = f"-Z threads={min(8, cpu_count)}"
# Cargo calls executables in $RUSTROOT/lib/rustlib/$TRIPLE/bin, we need
# to make sure the runtime linker also search $RUSTROOT/lib for libraries.
# This is only required on Unix, as Windows search dlls from PATH.
if os_name == "darwin":
env["DYLD_FALLBACK_LIBRARY_PATH"] = str(rust_sysroot / "lib")
elif os_name == "linux":
env["LD_LIBRARY_PATH"] = str(rust_sysroot / "lib")
if shutil.which("rustup"):
# Go through rustup proxies by default if available
env["RUSTUP_TOOLCHAIN"] = str(rust_sysroot)
else:
env["PATH"] = f"{rust_sysroot / "bin"}{os.pathsep}{env["PATH"]}"
# Cargo calls executables in $RUSTROOT/lib/rustlib/$TRIPLE/bin, we need
# to make sure the runtime linker also search $RUSTROOT/lib for libraries.
# This is only required on Unix, as Windows search dlls from PATH.
if os_name == "darwin":
env["DYLD_FALLBACK_LIBRARY_PATH"] = str(rust_sysroot / "lib")
elif os_name == "linux":
env["LD_LIBRARY_PATH"] = str(rust_sysroot / "lib")
return execv(["cargo", *cmds], env)

View File

@@ -79,6 +79,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := magiskboot
LOCAL_STATIC_LIBRARIES := \
libbase \
liblz4 \
libboot-rs
LOCAL_SRC_FILES := \

24
native/src/Cargo.lock generated
View File

@@ -636,11 +636,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "lz4_flex"
version = "0.11.5"
source = "git+https://github.com/PSeitz/lz4_flex.git?rev=e3e5138cff0cad6ca87d09b9d03b1f6017bbc370#e3e5138cff0cad6ca87d09b9d03b1f6017bbc370"
name = "lz4"
version = "1.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20b523e860d03443e98350ceaac5e71c6ba89aea7d960769ec3ce37f4de5af4"
dependencies = [
"twox-hash",
"lz4-sys",
]
[[package]]
name = "lz4-sys"
version = "1.11.1+lz4-1.10.0"
dependencies = [
"libc",
]
[[package]]
@@ -684,7 +692,7 @@ dependencies = [
"digest 0.11.0",
"fdt",
"flate2",
"lz4_flex",
"lz4",
"lzma-rust2",
"num-traits",
"p256",
@@ -1213,12 +1221,6 @@ dependencies = [
"syn",
]
[[package]]
name = "twox-hash"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c"
[[package]]
name = "typenum"
version = "1.19.0"

View File

@@ -34,7 +34,7 @@ quick-protobuf = "0.8.1"
flate2 = { version = "1.1.9", default-features = false }
bzip2 = "0.6.1"
zopfli = "0.8.3"
lz4_flex = { git = "https://github.com/PSeitz/lz4_flex.git", rev = "e3e5138cff0cad6ca87d09b9d03b1f6017bbc370", default-features = false, features = ["hc", "std", "frame"] }
lz4 = "1.28.1"
lzma-rust2 = { version = "0.16.2", default-features = false }
nix = "0.30.1"
bitflags = "2.11.0"
@@ -53,6 +53,7 @@ der = "0.8.0"
[patch.crates-io]
pb-rs = { git = "https://github.com/topjohnwu/quick-protobuf.git" }
quick-protobuf = { git = "https://github.com/topjohnwu/quick-protobuf.git" }
lz4-sys = { path = "external/lz4-sys" }
[workspace.lints.clippy]
unwrap_used = "deny"

View File

@@ -34,6 +34,6 @@ bytemuck = { workspace = true, features = ["derive", "min_const_generics"] }
num-traits = { workspace = true }
flate2 = { workspace = true, features = ["zlib-rs"] }
bzip2 = { workspace = true }
lz4_flex = { workspace = true, features = ["hc", "std", "frame"]}
lz4 = { workspace = true }
lzma-rust2 = { workspace = true, features = ["xz", "std", "encoder", "optimization"] }
zopfli = { workspace = true, features = ["gzip"] }

View File

@@ -7,9 +7,11 @@ use bzip2::write::BzEncoder;
use flate2::Compression as GzCompression;
use flate2::read::MultiGzDecoder;
use flate2::write::GzEncoder;
use lz4_flex::frame::{
BlockSize as LZ4BlockSize, FrameDecoder as LZ4FrameDecoder, FrameEncoder as LZ4FrameEncoder,
FrameInfo as LZ4FrameInfo,
use lz4::block::CompressionMode;
use lz4::liblz4::BlockChecksum;
use lz4::{
BlockMode, BlockSize, ContentChecksum, Decoder as LZ4FrameDecoder, Encoder as LZ4FrameEncoder,
EncoderBuilder as LZ4FrameEncoderBuilder,
};
use lzma_rust2::{CheckType, LzmaOptions, LzmaReader, LzmaWriter, XzOptions, XzReader, XzWriter};
use std::cmp::min;
@@ -49,7 +51,9 @@ impl<W: Write> WriteFinish<W> for BufWriter<ZopFliEncoder<W>> {
impl<W: Write> WriteFinish<W> for LZ4FrameEncoder<W> {
fn finish(self: Box<Self>) -> std::io::Result<W> {
Ok(Self::finish(*self)?)
let (w, r) = Self::finish(*self);
r?;
Ok(w)
}
}
@@ -61,31 +65,40 @@ impl<W: Write> WriteFinish<W> for LZ4FrameEncoder<W> {
// LZ4BlockEncoder
const LZ4_BLOCK_SIZE: usize = 0x800000;
const LZ4HC_CLEVEL_MAX: u8 = 12;
const LZ4HC_CLEVEL_MAX: i32 = 12;
const LZ4_MAGIC: u32 = 0x184c2102;
struct LZ4BlockEncoder<W: Write> {
write: W,
chunker: Chunker,
out_buf: Box<[u8]>,
total: u32,
is_lg: bool,
}
impl<W: Write> LZ4BlockEncoder<W> {
fn new(write: W, is_lg: bool) -> Self {
let out_sz = lz4::block::compress_bound(LZ4_BLOCK_SIZE).unwrap_or(LZ4_BLOCK_SIZE);
LZ4BlockEncoder {
write,
chunker: Chunker::new(LZ4_BLOCK_SIZE),
// SAFETY: all bytes will be initialized before it is used
out_buf: unsafe { Box::new_uninit_slice(out_sz).assume_init() },
total: 0,
is_lg,
}
}
fn encode_block(write: &mut W, chunk: &[u8]) -> std::io::Result<()> {
let compressed = lz4_flex::block::compress_hc_to_vec(chunk, LZ4HC_CLEVEL_MAX);
let block_size = compressed.len() as u32;
fn encode_block(write: &mut W, out_buf: &mut [u8], chunk: &[u8]) -> std::io::Result<()> {
let compressed_size = lz4::block::compress_to_buffer(
chunk,
Some(CompressionMode::HIGHCOMPRESSION(LZ4HC_CLEVEL_MAX)),
false,
out_buf,
)?;
let block_size = compressed_size as u32;
write.write_pod(&block_size)?;
write.write_all(&compressed)
write.write_all(&out_buf[..compressed_size])
}
}
@@ -110,7 +123,7 @@ impl<W: Write> Write for LZ4BlockEncoder<W> {
let (b, chunk) = self.chunker.add_data(buf);
buf = b;
if let Some(chunk) = chunk {
Self::encode_block(&mut self.write, chunk)?;
Self::encode_block(&mut self.write, &mut self.out_buf, chunk)?;
}
}
Ok(())
@@ -121,7 +134,7 @@ impl<W: Write> WriteFinish<W> for LZ4BlockEncoder<W> {
fn finish(mut self: Box<Self>) -> std::io::Result<W> {
let chunk = self.chunker.get_available();
if !chunk.is_empty() {
Self::encode_block(&mut self.write, chunk)?;
Self::encode_block(&mut self.write, &mut self.out_buf, chunk)?;
}
if self.is_lg {
self.write.write_pod(&self.total)?;
@@ -142,12 +155,10 @@ struct LZ4BlockDecoder<R: Read> {
impl<R: Read> LZ4BlockDecoder<R> {
fn new(read: R) -> Self {
let compressed_sz = lz4::block::compress_bound(LZ4_BLOCK_SIZE).unwrap_or(LZ4_BLOCK_SIZE);
Self {
read,
in_buf: unsafe {
Box::new_uninit_slice(lz4_flex::block::get_maximum_output_size(LZ4_BLOCK_SIZE))
.assume_init()
},
in_buf: unsafe { Box::new_uninit_slice(compressed_sz).assume_init() },
out_buf: unsafe { Box::new_uninit_slice(LZ4_BLOCK_SIZE).assume_init() },
out_len: 0,
out_pos: 0,
@@ -189,8 +200,11 @@ impl<R: Read> Read for LZ4BlockDecoder<R> {
}
}
self.out_len = lz4_flex::block::decompress_into(compressed_block, &mut self.out_buf)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
self.out_len = lz4::block::decompress_to_buffer(
compressed_block,
Some(LZ4_BLOCK_SIZE as i32),
&mut self.out_buf,
)?;
self.out_pos = 0;
}
let copy_len = min(buf.len(), self.out_len - self.out_pos);
@@ -218,14 +232,17 @@ pub fn get_encoder<'a, W: Write + 'a>(
None,
)?),
FileFormat::BZIP2 => Box::new(BzEncoder::new(w, BzCompression::best())),
FileFormat::LZ4 => Box::new(LZ4FrameEncoder::with_compression_level(
LZ4FrameInfo::new()
.block_size(LZ4BlockSize::Max4MB)
.block_checksums(true)
.content_checksum(true),
w,
LZ4HC_CLEVEL_MAX,
)),
FileFormat::LZ4 => {
let encoder = LZ4FrameEncoderBuilder::new()
.block_size(BlockSize::Max4MB)
.block_mode(BlockMode::Independent)
.checksum(ContentChecksum::ChecksumEnabled)
.block_checksum(BlockChecksum::BlockChecksumEnabled)
.level(9)
.auto_flush(true)
.build(w)?;
Box::new(encoder)
}
FileFormat::LZ4_LEGACY => Box::new(LZ4BlockEncoder::new(w, false)),
FileFormat::LZ4_LG => Box::new(LZ4BlockEncoder::new(w, true)),
FileFormat::ZOPFLI => {
@@ -250,7 +267,7 @@ pub fn get_decoder<'a, R: Read + 'a>(
FileFormat::XZ => Box::new(XzReader::new(r, true)),
FileFormat::LZMA => Box::new(LzmaReader::new_mem_limit(r, u32::MAX, None)?),
FileFormat::BZIP2 => Box::new(BzDecoder::new(r)),
FileFormat::LZ4 => Box::new(LZ4FrameDecoder::new(r)),
FileFormat::LZ4 => Box::new(LZ4FrameDecoder::new(r)?),
FileFormat::LZ4_LG | FileFormat::LZ4_LEGACY => Box::new(LZ4BlockDecoder::new(r)),
FileFormat::ZOPFLI | FileFormat::GZIP => Box::new(MultiGzDecoder::new(r)),
_ => unreachable!(),

View File

@@ -27,6 +27,8 @@ struct ResetProp {
context: bool,
#[argh(switch, short = 'n', long = none)]
skip_svc: bool,
#[argh(switch, short = 'c', long = "compact")]
compact: bool,
#[argh(option, short = 'f')]
file: Option<Utf8CString>,
#[argh(option, short = 'd', long = "delete")]
@@ -59,6 +61,7 @@ General flags:
-h,--help show this message
-v,--verbose print verbose output to stderr
-w switch to wait mode
-c,--compact compact property area
Read mode flags:
-p also read persistent properties from storage
@@ -177,6 +180,11 @@ impl ResetProp {
ret
}
fn compact(&self) -> bool {
debug!("resetprop: compact property area");
SYS_PROP.compact()
}
fn wait(&self) {
let key = &self.args[0];
let val = self.args.get(1).map(|s| &**s);
@@ -227,7 +235,11 @@ impl ResetProp {
}
fn run(self) -> LoggedResult<()> {
if self.wait_mode {
if self.compact {
if !self.compact() {
return log_err!();
}
} else if self.wait_mode {
self.wait();
} else if let Some(file) = &self.file {
self.load_file(file)?;
@@ -269,6 +281,9 @@ pub fn resetprop_main(argc: i32, argv: *mut *mut c_char) -> i32 {
}
special_mode += 1;
}
if cli.compact {
special_mode += 1;
}
if cli.file.is_some() {
special_mode += 1;
}

View File

@@ -82,6 +82,8 @@ unsafe extern "C" {
fn sys_prop_delete(key: CharPtr, prune: bool) -> i32;
#[link_name = "__system_property_get_context"]
fn sys_prop_get_context(key: CharPtr) -> CharPtr;
#[link_name = "__system_property_compact"]
fn sys_prop_compact() -> bool;
#[link_name = "__system_property_area_serial2"]
fn sys_prop_area_serial() -> u32;
}
@@ -175,6 +177,10 @@ impl SysProp {
unsafe { Utf8CStr::from_ptr_unchecked(sys_prop_get_context(key.as_ptr())) }
}
fn compact(&self) -> bool {
unsafe { sys_prop_compact() }
}
fn area_serial(&self) -> u32 {
unsafe { sys_prop_area_serial() }
}

View File

@@ -11,6 +11,18 @@ LOCAL_SRC_FILES := \
xz-embedded/xz_dec_stream.c
include $(BUILD_STATIC_LIBRARY)
# liblz4.a
include $(CLEAR_VARS)
LOCAL_MODULE := liblz4
LOCAL_C_INCLUDES := $(LOCAL_PATH)/lz4/lib
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_SRC_FILES := \
lz4/lib/lz4.c \
lz4/lib/lz4frame.c \
lz4/lib/lz4hc.c \
lz4/lib/xxhash.c
include $(BUILD_STATIC_LIBRARY)
SE_PATH := $(LOCAL_PATH)/selinux
# libsepol.a

1
native/src/external/lz4 vendored Submodule

Submodule native/src/external/lz4 added at d44371841a

10
native/src/external/lz4-sys/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "lz4-sys"
license = "MIT"
version = "1.11.1+lz4-1.10.0"
authors = [ "Jens Heyens <jens.heyens@ewetel.net>", "Artem V. Navrotskiy <bozaro@buzzsoft.ru>", "Patrick Marks <pmarks@gmail.com>"]
description = "Rust LZ4 sys package."
repository = "https://github.com/10xGenomics/lz4-rs"
[dependencies]
libc = "0.2"

480
native/src/external/lz4-sys/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,480 @@
#![allow(unexpected_cfgs)]
#![no_std]
extern crate libc;
#[cfg(not(all(
target_arch = "wasm32",
not(any(target_env = "wasi", target_os = "wasi"))
)))]
pub use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t};
#[cfg(all(
target_arch = "wasm32",
not(any(target_env = "wasi", target_os = "wasi"))
))]
extern crate alloc;
#[cfg(all(
target_arch = "wasm32",
not(any(target_env = "wasi", target_os = "wasi"))
))]
mod wasm_shim;
#[cfg(all(
target_arch = "wasm32",
not(any(target_env = "wasi", target_os = "wasi"))
))]
extern crate std;
#[cfg(all(
target_arch = "wasm32",
not(any(target_env = "wasi", target_os = "wasi"))
))]
pub use std::os::raw::{c_char, c_int, c_uint, c_ulonglong, c_void};
#[cfg(all(
target_arch = "wasm32",
not(any(target_env = "wasi", target_os = "wasi"))
))]
#[allow(non_camel_case_types)]
pub type size_t = usize;
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct LZ4FCompressionContext(pub *mut c_void);
unsafe impl Send for LZ4FCompressionContext {}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct LZ4FDecompressionContext(pub *mut c_void);
unsafe impl Send for LZ4FDecompressionContext {}
pub type LZ4FErrorCode = size_t;
#[derive(Clone, Debug)]
#[repr(u32)]
pub enum BlockSize {
Default = 0, // Default - 64KB
Max64KB = 4,
Max256KB = 5,
Max1MB = 6,
Max4MB = 7,
}
impl BlockSize {
pub fn get_size(&self) -> usize {
match self {
&BlockSize::Default | &BlockSize::Max64KB => 64 * 1024,
&BlockSize::Max256KB => 256 * 1024,
&BlockSize::Max1MB => 1 * 1024 * 1024,
&BlockSize::Max4MB => 4 * 1024 * 1024,
}
}
}
#[derive(Clone, Debug)]
#[repr(u32)]
pub enum BlockMode {
Linked = 0,
Independent,
}
#[derive(Clone, Debug)]
#[repr(u32)]
pub enum ContentChecksum {
NoChecksum = 0,
ChecksumEnabled,
}
#[derive(Clone, Debug)]
#[repr(u32)]
pub enum FrameType {
Frame = 0,
SkippableFrame,
}
#[derive(Clone, Debug)]
#[repr(u32)]
pub enum BlockChecksum {
NoBlockChecksum = 0,
BlockChecksumEnabled,
}
#[derive(Debug)]
#[repr(C)]
pub struct LZ4FFrameInfo {
pub block_size_id: BlockSize,
pub block_mode: BlockMode,
pub content_checksum_flag: ContentChecksum,
pub frame_type: FrameType,
pub content_size: c_ulonglong,
pub dict_id: c_uint,
pub block_checksum_flag: BlockChecksum,
}
#[derive(Debug)]
#[repr(C)]
pub struct LZ4FPreferences {
pub frame_info: LZ4FFrameInfo,
pub compression_level: c_uint, // 0 == default (fast mode); values above 16 count as 16
pub auto_flush: c_uint, // 1 == always flush : reduce need for tmp buffer
pub favor_dec_speed: c_uint, // 1 == favor decompression speed over ratio, requires level 10+
pub reserved: [c_uint; 3],
}
#[derive(Debug)]
#[repr(C)]
pub struct LZ4FCompressOptions {
pub stable_src: c_uint, /* 1 == src content will remain available on future calls
* to LZ4F_compress(); avoid saving src content within tmp
* buffer as future dictionary */
pub reserved: [c_uint; 3],
}
#[derive(Debug)]
#[repr(C)]
pub struct LZ4FDecompressOptions {
pub stable_dst: c_uint, /* guarantee that decompressed data will still be there on next
* function calls (avoid storage into tmp buffers) */
pub reserved: [c_uint; 3],
}
#[derive(Debug)]
#[repr(C)]
pub struct LZ4StreamEncode(c_void);
#[derive(Debug)]
#[repr(C)]
pub struct LZ4StreamDecode(c_void);
pub const LZ4F_VERSION: c_uint = 100;
extern "C" {
// int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
#[allow(non_snake_case)]
pub fn LZ4_compress_default(
source: *const c_char,
dest: *mut c_char,
sourceSize: c_int,
maxDestSize: c_int,
) -> c_int;
// int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration);
#[allow(non_snake_case)]
pub fn LZ4_compress_fast(
source: *const c_char,
dest: *mut c_char,
sourceSize: c_int,
maxDestSize: c_int,
acceleration: c_int,
) -> c_int;
// int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel);
#[allow(non_snake_case)]
pub fn LZ4_compress_HC(
src: *const c_char,
dst: *mut c_char,
srcSize: c_int,
dstCapacity: c_int,
compressionLevel: c_int,
) -> c_int;
// int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
#[allow(non_snake_case)]
pub fn LZ4_decompress_safe(
source: *const c_char,
dest: *mut c_char,
compressedSize: c_int,
maxDecompressedSize: c_int,
) -> c_int;
// unsigned LZ4F_isError(LZ4F_errorCode_t code);
pub fn LZ4F_isError(code: size_t) -> c_uint;
// const char* LZ4F_getErrorName(LZ4F_errorCode_t code);
pub fn LZ4F_getErrorName(code: size_t) -> *const c_char;
// LZ4F_createCompressionContext() :
// The first thing to do is to create a compressionContext object, which will be used in all
// compression operations.
// This is achieved using LZ4F_createCompressionContext(), which takes as argument a version
// and an LZ4F_preferences_t structure.
// The version provided MUST be LZ4F_VERSION. It is intended to track potential version
// differences between different binaries.
// The function will provide a pointer to a fully allocated LZ4F_compressionContext_t object.
// If the result LZ4F_errorCode_t is not zero, there was an error during context creation.
// Object can release its memory using LZ4F_freeCompressionContext();
//
// LZ4F_errorCode_t LZ4F_createCompressionContext(
// LZ4F_compressionContext_t* LZ4F_compressionContextPtr,
// unsigned version);
pub fn LZ4F_createCompressionContext(
ctx: &mut LZ4FCompressionContext,
version: c_uint,
) -> LZ4FErrorCode;
// LZ4F_errorCode_t LZ4F_freeCompressionContext(
// LZ4F_compressionContext_t LZ4F_compressionContext);
pub fn LZ4F_freeCompressionContext(ctx: LZ4FCompressionContext) -> LZ4FErrorCode;
// LZ4F_compressBegin() :
// will write the frame header into dstBuffer.
// dstBuffer must be large enough to accommodate a header (dstMaxSize). Maximum header
// size is 19 bytes.
// The LZ4F_preferences_t structure is optional : you can provide NULL as argument, all
// preferences will then be set to default.
// The result of the function is the number of bytes written into dstBuffer for the header
// or an error code (can be tested using LZ4F_isError())
//
// size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext,
// void* dstBuffer,
// size_t dstMaxSize,
// const LZ4F_preferences_t* preferencesPtr);
pub fn LZ4F_compressBegin(
ctx: LZ4FCompressionContext,
dstBuffer: *mut u8,
dstMaxSize: size_t,
preferencesPtr: *const LZ4FPreferences,
) -> LZ4FErrorCode;
// LZ4F_compressBound() :
// Provides the minimum size of Dst buffer given srcSize to handle worst case situations.
// preferencesPtr is optional : you can provide NULL as argument, all preferences will then
// be set to default.
// Note that different preferences will produce in different results.
//
// size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr);
pub fn LZ4F_compressBound(
srcSize: size_t,
preferencesPtr: *const LZ4FPreferences,
) -> LZ4FErrorCode;
// LZ4F_compressUpdate()
// LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary.
// The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure
// compression completion even in worst case.
// If this condition is not respected, LZ4F_compress() will fail (result is an errorCode)
// You can get the minimum value of dstMaxSize by using LZ4F_compressBound()
// The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.
// The result of the function is the number of bytes written into dstBuffer : it can be zero,
// meaning input data was just buffered.
// The function outputs an error code if it fails (can be tested using LZ4F_isError())
//
// size_t LZ4F_compressUpdate(LZ4F_compressionContext_t compressionContext,
// void* dstBuffer,
// size_t dstMaxSize,
// const void* srcBuffer,
// size_t srcSize,
// const LZ4F_compressOptions_t* compressOptionsPtr);
pub fn LZ4F_compressUpdate(
ctx: LZ4FCompressionContext,
dstBuffer: *mut u8,
dstMaxSize: size_t,
srcBuffer: *const u8,
srcSize: size_t,
compressOptionsPtr: *const LZ4FCompressOptions,
) -> size_t;
// LZ4F_flush()
// Should you need to create compressed data immediately, without waiting for a block
// to be be filled, you can call LZ4_flush(), which will immediately compress any remaining
// data buffered within compressionContext.
// The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.
// The result of the function is the number of bytes written into dstBuffer
// (it can be zero, this means there was no data left within compressionContext)
// The function outputs an error code if it fails (can be tested using LZ4F_isError())
//
// size_t LZ4F_flush(LZ4F_compressionContext_t compressionContext,
// void* dstBuffer,
// size_t dstMaxSize,
// const LZ4F_compressOptions_t* compressOptionsPtr);
pub fn LZ4F_flush(
ctx: LZ4FCompressionContext,
dstBuffer: *mut u8,
dstMaxSize: size_t,
compressOptionsPtr: *const LZ4FCompressOptions,
) -> LZ4FErrorCode;
// LZ4F_compressEnd()
// When you want to properly finish the compressed frame, just call LZ4F_compressEnd().
// It will flush whatever data remained within compressionContext (like LZ4_flush())
// but also properly finalize the frame, with an endMark and a checksum.
// The result of the function is the number of bytes written into dstBuffer
// (necessarily >= 4 (endMark size))
// The function outputs an error code if it fails (can be tested using LZ4F_isError())
// The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.
// compressionContext can then be used again, starting with LZ4F_compressBegin().
//
// size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext,
// void* dstBuffer,
// size_t dstMaxSize,
// const LZ4F_compressOptions_t* compressOptionsPtr);
pub fn LZ4F_compressEnd(
ctx: LZ4FCompressionContext,
dstBuffer: *mut u8,
dstMaxSize: size_t,
compressOptionsPtr: *const LZ4FCompressOptions,
) -> LZ4FErrorCode;
// LZ4F_createDecompressionContext() :
// The first thing to do is to create a decompressionContext object, which will be used
// in all decompression operations.
// This is achieved using LZ4F_createDecompressionContext().
// The version provided MUST be LZ4F_VERSION. It is intended to track potential version
// differences between different binaries.
// The function will provide a pointer to a fully allocated and initialized
// LZ4F_decompressionContext_t object.
// If the result LZ4F_errorCode_t is not OK_NoError, there was an error during
// context creation.
// Object can release its memory using LZ4F_freeDecompressionContext();
//
// LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t* ctxPtr,
// unsigned version);
pub fn LZ4F_createDecompressionContext(
ctx: &mut LZ4FDecompressionContext,
version: c_uint,
) -> LZ4FErrorCode;
// LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t ctx);
pub fn LZ4F_freeDecompressionContext(ctx: LZ4FDecompressionContext) -> LZ4FErrorCode;
// LZ4F_getFrameInfo()
// This function decodes frame header information, such as blockSize.
// It is optional : you could start by calling directly LZ4F_decompress() instead.
// The objective is to extract header information without starting decompression, typically
// for allocation purposes.
// LZ4F_getFrameInfo() can also be used *after* starting decompression, on a
// valid LZ4F_decompressionContext_t.
// The number of bytes read from srcBuffer will be provided within *srcSizePtr
// (necessarily <= original value).
// You are expected to resume decompression from where it stopped (srcBuffer + *srcSizePtr)
// The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for
// next call, or an error code which can be tested using LZ4F_isError().
//
// size_t LZ4F_getFrameInfo(LZ4F_decompressionContext_t ctx,
// LZ4F_frameInfo_t* frameInfoPtr,
// const void* srcBuffer, size_t* srcSizePtr);
pub fn LZ4F_getFrameInfo(
ctx: LZ4FDecompressionContext,
frameInfoPtr: &mut LZ4FFrameInfo,
srcBuffer: *const u8,
srcSizePtr: &mut size_t,
) -> LZ4FErrorCode;
// LZ4F_decompress()
// Call this function repetitively to regenerate data compressed within srcBuffer.
// The function will attempt to decode *srcSizePtr bytes from srcBuffer, into dstBuffer of
// maximum size *dstSizePtr.
//
// The number of bytes regenerated into dstBuffer will be provided within *dstSizePtr
// (necessarily <= original value).
//
// The number of bytes read from srcBuffer will be provided within *srcSizePtr
// (necessarily <= original value).
// If number of bytes read is < number of bytes provided, then decompression operation
// is not completed. It typically happens when dstBuffer is not large enough to contain
// all decoded data.
// LZ4F_decompress() must be called again, starting from where it stopped
// (srcBuffer + *srcSizePtr)
// The function will check this condition, and refuse to continue if it is not respected.
//
// dstBuffer is supposed to be flushed between each call to the function, since its content
// will be overwritten.
// dst arguments can be changed at will with each consecutive call to the function.
//
// The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for
// next call.
// Schematically, it's the size of the current (or remaining) compressed block + header of
// next block.
// Respecting the hint provides some boost to performance, since it does skip intermediate
// buffers.
// This is just a hint, you can always provide any srcSize you want.
// When a frame is fully decoded, the function result will be 0. (no more data expected)
// If decompression failed, function result is an error code, which can be tested
// using LZ4F_isError().
//
// size_t LZ4F_decompress(LZ4F_decompressionContext_t ctx,
// void* dstBuffer, size_t* dstSizePtr,
// const void* srcBuffer, size_t* srcSizePtr,
// const LZ4F_decompressOptions_t* optionsPtr);
pub fn LZ4F_decompress(
ctx: LZ4FDecompressionContext,
dstBuffer: *mut u8,
dstSizePtr: &mut size_t,
srcBuffer: *const u8,
srcSizePtr: &mut size_t,
optionsPtr: *const LZ4FDecompressOptions,
) -> LZ4FErrorCode;
// int LZ4_versionNumber(void)
pub fn LZ4_versionNumber() -> c_int;
// int LZ4_compressBound(int isize)
pub fn LZ4_compressBound(size: c_int) -> c_int;
// LZ4_stream_t* LZ4_createStream(void)
pub fn LZ4_createStream() -> *mut LZ4StreamEncode;
// int LZ4_compress_continue(LZ4_stream_t* LZ4_streamPtr,
// const char* source,
// char* dest,
// int inputSize)
pub fn LZ4_compress_continue(
LZ4_stream: *mut LZ4StreamEncode,
source: *const u8,
dest: *mut u8,
input_size: c_int,
) -> c_int;
// int LZ4_freeStream(LZ4_stream_t* LZ4_streamPtr)
pub fn LZ4_freeStream(LZ4_stream: *mut LZ4StreamEncode) -> c_int;
// int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode,
// const char* dictionary,
// int dictSize)
pub fn LZ4_setStreamDecode(
LZ4_stream: *mut LZ4StreamDecode,
dictionary: *const u8,
dict_size: c_int,
) -> c_int;
// LZ4_streamDecode_t* LZ4_createStreamDecode(void)
pub fn LZ4_createStreamDecode() -> *mut LZ4StreamDecode;
// int LZ4_decompress_safe_continue(LZ4_streamDecode_t* LZ4_streamDecode,
// const char* source,
// char* dest,
// int compressedSize,
// int maxDecompressedSize)
pub fn LZ4_decompress_safe_continue(
LZ4_stream: *mut LZ4StreamDecode,
source: *const u8,
dest: *mut u8,
compressed_size: c_int,
max_decompressed_size: c_int,
) -> c_int;
// int LZ4_freeStreamDecode(LZ4_streamDecode_t* LZ4_stream)
pub fn LZ4_freeStreamDecode(LZ4_stream: *mut LZ4StreamDecode) -> c_int;
// LZ4F_resetDecompressionContext()
// In case of an error, the context is left in "undefined" state.
// In which case, it's necessary to reset it, before re-using it.
// This method can also be used to abruptly stop any unfinished decompression,
// and start a new one using same context resources.
pub fn LZ4F_resetDecompressionContext(ctx: LZ4FDecompressionContext);
}
#[test]
fn test_version_number() {
unsafe {
LZ4_versionNumber();
}
}
#[test]
fn test_frame_info_size() {
assert_eq!(core::mem::size_of::<LZ4FFrameInfo>(), 32);
}

View File

@@ -0,0 +1,123 @@
//! A shim for the libc functions used in lz4-rs that are not available when building for wasm
//! targets. Adapted from the shim present in the [zstd](https://github.com/gyscos/zstd-rs) crate.
//! zstd-rs license here:
//! The MIT License (MIT)
//! Copyright (c) 2016 Alexandre Bury
//!
//! Permission is hereby granted, free of charge, to any person obtaining a copy of this software
//! and associated documentation files (the "Software"), to deal in the Software without
//! restriction, including without limitation the rights to use, copy, modify, merge, publish,
//! distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
//! Software is furnished to do so, subject to the following conditions:
//!
//! The above copyright notice and this permission notice shall be included in all copies or
//! substantial portions of the Software.
//!
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
//! BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//! NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//! DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
use alloc::alloc::{alloc, alloc_zeroed, dealloc, Layout};
use core::ffi::{c_int, c_void};
const USIZE_ALIGN: usize = core::mem::align_of::<usize>();
const USIZE_SIZE: usize = core::mem::size_of::<usize>();
#[no_mangle]
pub extern "C" fn rust_lz4_wasm_shim_malloc(size: usize) -> *mut c_void {
wasm_shim_alloc::<false>(size)
}
#[no_mangle]
pub extern "C" fn rust_lz4_wasm_shim_memcmp(
str1: *const c_void,
str2: *const c_void,
n: usize,
) -> i32 {
// Safety: function contracts requires str1 and str2 at least `n`-long.
unsafe {
let str1: &[u8] = core::slice::from_raw_parts(str1 as *const u8, n);
let str2: &[u8] = core::slice::from_raw_parts(str2 as *const u8, n);
match str1.cmp(str2) {
core::cmp::Ordering::Less => -1,
core::cmp::Ordering::Equal => 0,
core::cmp::Ordering::Greater => 1,
}
}
}
#[no_mangle]
pub extern "C" fn rust_lz4_wasm_shim_calloc(nmemb: usize, size: usize) -> *mut c_void {
// note: calloc expects the allocation to be zeroed
wasm_shim_alloc::<true>(nmemb * size)
}
#[inline]
fn wasm_shim_alloc<const ZEROED: bool>(size: usize) -> *mut c_void {
// in order to recover the size upon free, we store the size below the allocation
// special alignment is never requested via the malloc API,
// so it's not stored, and usize-alignment is used
// memory layout: [size] [allocation]
let full_alloc_size = size + USIZE_SIZE;
unsafe {
let layout = Layout::from_size_align_unchecked(full_alloc_size, USIZE_ALIGN);
let ptr = if ZEROED {
alloc_zeroed(layout)
} else {
alloc(layout)
};
// SAFETY: ptr is usize-aligned and we've allocated sufficient memory
ptr.cast::<usize>().write(full_alloc_size);
ptr.add(USIZE_SIZE).cast()
}
}
#[no_mangle]
pub unsafe extern "C" fn rust_lz4_wasm_shim_free(ptr: *mut c_void) {
// the layout for the allocation needs to be recovered for dealloc
// - the size must be recovered from directly below the allocation
// - the alignment will always by USIZE_ALIGN
let alloc_ptr = ptr.sub(USIZE_SIZE);
// SAFETY: the allocation routines must uphold having a valid usize below the provided pointer
let full_alloc_size = alloc_ptr.cast::<usize>().read();
let layout = Layout::from_size_align_unchecked(full_alloc_size, USIZE_ALIGN);
dealloc(alloc_ptr.cast(), layout);
}
#[no_mangle]
pub unsafe extern "C" fn rust_lz4_wasm_shim_memcpy(
dest: *mut c_void,
src: *const c_void,
n: usize,
) -> *mut c_void {
core::ptr::copy_nonoverlapping(src as *const u8, dest as *mut u8, n);
dest
}
#[no_mangle]
pub unsafe extern "C" fn rust_lz4_wasm_shim_memmove(
dest: *mut c_void,
src: *const c_void,
n: usize,
) -> *mut c_void {
core::ptr::copy(src as *const u8, dest as *mut u8, n);
dest
}
#[no_mangle]
pub unsafe extern "C" fn rust_lz4_wasm_shim_memset(
dest: *mut c_void,
c: c_int,
n: usize,
) -> *mut c_void {
core::ptr::write_bytes(dest as *mut u8, c as u8, n);
dest
}