پرش به محتوای اصلی

انتشار منبع AOSP آنقدر دیر است که توسعه دهندگان کتابخانه ها را جدا می کنند تا اشکالات را گزارش کنند

هکرنیوز۱۴۰۵ مهر ۲۲, چهارشنبه، ساعت ۰۹:۴۸حدود 4 دقیقه مطالعه

آدرس مقاله: https://github.com/android/ndk/issues/2260 آدرس نظرات: https://news.ycombinator.com/item?id=50083130 امتیاز: 302 # نظرات: 142

### توضیحات

در نسخه‌های Android 17 از سپتامبر 2026، «wcscspn()» و «wcspbrk()» در اولین نویسه رشته که >= U+0100 است، هر زمان که مجموعه رد دو یا چند کاراکتر داشته باشد که همگی <U+0100 هستند، متوقف می‌شوند. شخصیت به عنوان یک مسابقه گزارش می شود حتی اگر در مجموعه نیست. «wcsspn()»، «wcschr()»، «wcsrchr()»، «wmemchr()» و «wcsstr()» صحیح هستند.

هر کدی که رشته‌های گسترده را برای جداکننده‌های ASCII اسکن می‌کند، به‌عنوان مثال نویسه‌های خط جدید یا حروف عام، به محض اینکه متن حاوی نویسه‌های Emoji، CJK، سیریلیک، یونانی یا لاتین Extended باشد، شکسته می‌شود.

## متاثر / بی تأثیر

| دستگاه | ساخت | نتیجه | |---|---|---| | پیکسل 7 | google/panther/panther:17/CP3A.260905.009/16091614:user/release-keys | شکسته | | پیکسل 8a | google/akita/akita:17/CP3A.260905.009/16091614:user/release-keys (پچ 05-09-2026) | شکسته | | Nothing Phone 2 | Nothing/PongEEA/Pong:16/BQ2A.250721.001-BP2A.250605.031.A3 (پچ 2026-08-01) | باشه |

منابع عمومی انتشار android17 (android-17.0.0_r1، ژوئن 2026) «wcscspn»/«wcspbrk» را از خارجی/llvm-libc می‌سازند، که یک حلقه تودرتوی ساده روی «wchar_t» است و درست است. کد در نسخه های سپتامبر متفاوت است (به "مکانیسم" مراجعه کنید)، بنابراین رگرسیون بین نسخه های ژوئن و سپتامبر معرفی شد.

## تولید کننده

با NDK («aarch64-linux-android30-clang» بسازید)، به «/data/local/tmp» فشار دهید، با «adb shell» اجرا کنید:

``ج #include <stdio.h> #include <wchar.h>

int main (void) { wchar_t s[] = {'a', 0x1F680, 0x100, 'b', 'x', '\n', 0}; printf("wcscspn(s, L\"x\\n\") = %zu (4 مورد انتظار)\n", wcscspn(s, L"x\n")); printf("wcspbrk(s, L\"x\\n\") = شاخص %ld (4 مورد انتظار)\n", (long)(wcspbrk(s, L"x\n") - s)); printf("wcsspn(s, L\"a\\U0001F680\") = %zu (2 مورد انتظار)\n", wcsspn(s, L"a\U0001F680")); بازگشت 0; } ```

خروجی در CP3A.260905.009:

``` wcscspn(s، L"x\n") = 1 (4 مورد انتظار) wcspbrk(s، L"x\n") = شاخص 1 (انتظار می رود 4) wcsspn(s، L"a\U0001F680") = 2 (2 مورد انتظار) ```

جابجایی از هر نقطه کد از U+0001 تا U+10FFFF (پرش از جانشین‌ها و دو عضو مجموعه) با «wcscspn(L"<cp>\n", L"x\n")" به جای 1 برای 1،111،808 نقطه کد: هر یک از U+0100 تا U+1، 0 را برمی‌گرداند. U+0001 تا U+00FF صحیح است.

کدام اشکال مجموعه آن را تحریک می کند (همه در پیکسل 8a اندازه گیری شده اند):

| رد مجموعه | نتیجه | |---|---| | یک شخصیت | باشه | | دو یا چند نویسه، همه < U+0100 (به عنوان مثال `L"x\n"`، `L"\xe9\n"`) | شکسته | | دو یا چند کاراکتر، حداقل یک >= U+0100 | باشه | | انبار کاه محدود به U+0080..U+00FF | باشه |

## مکانیسم (از libc.so ارسال شده)

جداسازی «wcscspn» در «/apex/com.android.runtime/lib64/bionic/libc.so» در CP3A.260905.009 سه مسیر انتخاب شده توسط مجموعه را نشان می دهد:

1. یک شخصیت: یک حلقه مقایسه ساده. درست است. 2. دو یا چند کاراکتر: یک جدول 256 بایتی "bool" روی پشته از مجموعه پر می شود در حالی که کاراکترهای مجموعه در 1..0xFF هستند. اگر یک کاراکتر مجموعه >= 0x100 دیده شود، تابع به فراخوانی «wcschr()» برای هر کاراکتر انبار کاه برمی گردد. درست است. 3. در غیر این صورت انبار کاه روی میز اسکن می شود:

``` a2564: ldrb w8, [x9, x8] ; جدول[c] a2568: tbnz w8, #0, a2578 ; در مجموعه -> توقف (درست) a256c: ldr w8، [x22، #0x4]! ; شخصیت بعدی a2570: cmp w8، #0x100 a2574: b.lo a2564 ; c <0x100 -> به اسکن کردن ادامه دهید a2578: ... ; c >= 0x100 -> STOP، به عنوان یک تطابق گزارش شده است ```

یک کاراکتر >= 0x100 نمی تواند در مجموعه ای باشد که همه اعضای آن <0x100 هستند، بنابراین برای «wcscspn» اسکن باید از آن گذشته باشد. کد به جای آن متوقف می شود. `wcsspn` ساختار یکسانی دارد و در آنجا توقف پاسخ صحیح است (کاراکتر در مجموعه نگهداری نیست) به همین دلیل است که فقط توابع مکمل اشتباه هستند. «wcspbrk» در بالای این اسکن پیاده‌سازی می‌شود و اشکال را به ارث می‌برد.

تست بیونیک موجود «TEST(wchar، wcspbrk)» در tests/wchar_test.cpp فقط از ورودی ASCII استفاده می‌کند، بنابراین این مورد را نمی‌گیرد. آزمایشی مانند `EXPECT_EQ(3u، wcscspn(L"aĀb\n، L"x\n"))" این کار را انجام می دهد.

## تاثیر در دنیای واقعی

Visual Pinball در Android (libwinevbs، ساخت یونیکس از موتور vbscript Wine) پس از به‌روزرسانی ماه سپتامبر، هر جدولی را که منبع VBScript حاوی یک نظر با شکلک باشد، بارگیری نمی‌کند: lexer از «wcspbrk(ptr, L"\n\r") برای رد کردن نظرات، دریافت موقعیت اولین emoji، و گزارش "In line" از «wcspbrk(ptr, L"\n\r") استفاده می‌کند. «FileSystem.MoveFolder» نیز به همین ترتیب، هر مسیری را که حاوی یک کاراکتر >= U+0100 است به عنوان یک الگوی عام از طریق «wcspbrk(src, L"*?><")" در نظر گرفت.

در پایین دست با جایگزین کردن تماس‌ها با حلقه‌های ساده کار کرد: https://github.com/vpinball/libwinevbs/pull/41 (ارسال شده در https://github.com/vpinball/vpinball/commit/e7837322f4).

جداسازی کامل عملکردهای آسیب دیده و منابع پروب در صورت درخواست در دسترس هستند.

### من از یک NDK پشتیبانی شده استفاده می کنم

- [x] من بررسی کرده ام و NDK مورد استفاده من در حال حاضر پشتیبانی می شود

### نسخه های تحت تأثیر

r29

خواندن متن کامل در هکرنیوزبه زبان اصلی، در سایت ناشر باز می‌شود
متن اصلی (انگلیسی)

AOSP Source Releases Are So Late Developers Disassemble Libraries to Report Bugs

Article URL: https://github.com/android/ndk/issues/2260 Comments URL: https://news.ycombinator.com/item?id=50083130 Points: 302 # Comments: 142

همه‌ی اخبار فناوری