· kaynak Hacker News – Front Page (native)
Android 17 bionic hatası wcscspn ve wcspbrk'ın U+00FF üstü her geniş karakterle eşleşmesine yol açıyor
Eylül 2026 Android 17 yapılarındaki bir regresyon, bionic'in geniş dizge fonksiyonları wcscspn() ve wcspbrk()'ın U+0100 ve üzeri her karakterde yanlış eşleşme bildirmesine neden oluyor. Sorunun kaynağı, cihazlarda dağıtılan libc'nin disassemble edilmesiyle tespit edildi.
Hata
Google'ın Android NDK issue tracker'ına açılan ve Hacker News ana sayfasına da taşan bir hata raporu, Android 17'nin C kütüphanesi bionic'teki bir regresyonu belgeliyor. Eylül 2026 yapılarında (CP3A.260905.009) — bir Pixel 7 ve bir Pixel 8a'da doğrulandı — wcscspn() ve wcspbrk() geniş karakter fonksiyonları, reject seti U+0100'ün altında iki veya daha fazla karakter içerdiği sürece U+0100 ve üzeri herhangi bir karakterde eşleşme bildiriyor. Android 16'yı çalıştırmaya devam eden bir Nothing Phone 2 doğru davranıyor, yani sorun yeni sürüme özgü.
Rapor kompakt bir yeniden üretici de içeriyor. 'a', bir emoji (U+1F680), U+0100, 'b', 'x' ve bir yeni satır içeren bir dizgeye karşı L"x\n" reject setiyle wcscspn() çağrıldığında 4 yerine 1 dönüyor: tarama emoji'de duruyor ve onu eşleşme olarak değerlendiriyor. Neredeyse tüm Unicode aralığını kapsayan bir tarama, U+0100'ten U+10FFFF'e kadar her kod noktasının — yani vekil kodlar (surrogate) ve set üyeleri hariç yaklaşık 1.111.808 karakterin — yanlış işlendiğini, buna karşılık U+0001'den U+00FF'ye kadar her şeyin doğru çalıştığını ortaya koydu.
Setin biçimi hatanın ortaya çıkıp çıkmayacağını belirliyor. Tek karakterli setler güvenli; U+0100 veya üzerinde en az bir karakter içeren setler de güvenli, çünkü o yol wcschr()'a geri düşüyor. Hatayı yalnızca tamamen düşük değerlerden oluşan çok karakterli setler tetikliyor. İlgili wcsspn(), wcschr(), wcsrchr(), wmemchr() ve wcsstr() fonksiyonlarının tümü doğru davranıyor.
Dağıtılan kütüphanenin disassemble edilmesiyle bulundu
Hikayenin en çarpıcı yanı ise nedenin nasıl ortaya çıkarıldığı. Rapora göre, kamuya açık Android 17 kaynak bırakımı (haziran 2026 tarihli android-17.0.0_r1), wcscspn ve wcspbrk'ı external/llvm-libc üzerinden wchar_t üzerinde düz bir iç içe döngü olarak derliyor ve bu doğru. Yani regresyon, haziran kaynak anlık görüntüsü ile eylül cihaz yapıları arasına, henüz yayınlanmamış kodda girmiş.
Eşleşen bir kaynak olmadığından, raporlayıcı cihazlarda gelen /apex/com.android.runtime/lib64/bionic/libc.so dosyasını disassemble etti. Disassembly, sete göre seçilen üç kod yolu gösteriyor: tek karakterli setler için basit bir karşılaştırma döngüsü, bir set üyesi U+0100'e ulaştığında wcschr() tabanlı bir geri dönüş ve — diğer her şey için — yığında (stack) oluşturulan 256 girişli bir boolean tablo. Bu son yolda tarama döngüsü her karakteri tabloya karşı kontrol ediyor, ancak 0x100 veya üzerinde bir karakter yüklediğinde taramayı sonlandıran ve eşleşme bildiren bir dala giriyor. Üyelerinin tümü U+0100'ün altında olan bir sete bu kadar büyük bir karakter asla ait olamaz, dolayısıyla doğru bir wcscspn devam etmek zorundadır. wcsspn aynı yapıyı paylaşıyor, ancak o fonksiyonda durmak tesadüfen doğru cevap; bu da yalnızca tamamlayıcı fonksiyonların neden hatalı olduğunu açıklıyor. wcspbrk aynı taramanın üzerine inşa edilmiş ve hatayı miras almış.
Gerçek dünyadaki etkisi ve bir test boşluğu
Rapor, hatayı Android'de Visual Pinball'daki somut bir bozulmaya bağlıyor; bu uygulamanın libwinevbs bileşeni, Wine'ın VBScript motorunun bir Unix yapısı. Eylül güncellemesinden sonra uygulama, VBScript kaynağının içindeki bir yorumda emoji bulunan hiçbir masayı yüklememeye başladı: lexer yorumları yeni satır/satır başı setiyle wcspbrk kullanarak atlıyordu, emojinin konumunu satırın sonu yerine aldı ve "Invalid character" hatası verdi. FileSystem.MoveFolder benzer bir başarısızlık yaşadı; U+0100 veya üzerinde karakter içeren her yolu wildcard örüntüsü olarak değerlendirdi. Proje kendi çözümünü gönderdi ve çağrıları elle yazılmış döngülerle değiştirdi.
Google'ın kendi testleri hatayı yakalayamadı, çünkü mevcut bionic wcspbrk testi yalnızca ASCII girdi kullanıyor. Rapor, wcscspn(L"aĀb\n", L"x\n") gibi bir durumun kontrol edilmesinin hatayı hemen yakalayacağını belirtiyor. Sorun, halen desteklenen NDK r29'a açıldı.
Neden önemli
Geniş dizgeleri ASCII ayırıcılar — yeni satır, wildcard, ayraç — için tarayan herhangi bir yerel Android kodu, metin bir emoji veya CJK, Kiril, Yunan ya da Latin Extended karakteri içerdiğinde sessizce yanlış ayrıştıracaktır; yani kullanıcıların ürettiği sıradan içerikle karşılaşıldığında. Hata yalnızca ASCII kullanan testlere görünmezdir, dolayısıyla uygulamalar yalnızca üretimde ortaya çıkan şekillerde çökebilir veya ayrıştırmayı bozabilir.
Bu olay ayrıca AOSP'nin geciken kaynak yayınlarının pratik maliyetini gösteriyor. Faydalı, tek satırla teşhis edilebilir bir hata raporu açmak isteyen bir katkıcı, yayınlanan ağacın cihazlarda gelenle uyuşmadığı için bir sistem ikili dosyasını tersine mühendislik yapmak zorunda kaldı. Google bu boşluğu — ya da dal koşulunu — düzelteneye kadar, Android 17'yi hedefleyen geliştiriciler bu standart kütüphane fonksiyonlarını şüpheli olarak görmek zorunda.
- #android
- #bionic
- #libc
- #unicode
- #ndk
- #aosp