[Firebase/Database] Don't link with icucore. (#626)

This avoids a problem where we might accidentally link with private symbols
exported by libicucore.dylib instead of the same symbols provided in a static
library.

This would show up as an App Store rejection:

    TMS-90338: Non-public API usage - The app references non-public symbols:
    _ubrk_openRules, _ucal_add, _ucal_close, _ucal_get, _ucal_getAttribute,
    _ucal_getKeywordValuesForLocale, _ucal_getNow, _ucal_getTimeZoneDisplayName,
    _ucal_getTimeZoneIDForWindowsID, _ucal_getWindowsTimeZoneID, _ucal_open,
    _ucal_openTimeZoneIDEnumeration, _ucal_set, _ucal_setMillis, _ucol_close,
    _ucol_closeElements, _ucol_getOffset, _ucol_getRules, _ucol_getSortKey,
    _ucol_getStrength, _ucol_getVersion, _ucol_next, _ucol_open,
    _ucol_openElements, _ucol_openRules, _ucol_previous, _ucol_safeClone,
    _ucol_setAttribute, _ucol_setVariableTop, _ucol_strcoll, _ucurr_forLocale,
    _ucurr_getName, _udat_close, _udat_countSymbols, _udat_format,
    _udat_getSymbols, _udat_open, _udat_setCalendar, _udat_toPattern,
    _udata_setCommonData, _udatpg_close, _udatpg_getBestPattern, _udatpg_open,
    _uenum_close, _uenum_count, _uenum_next, _uldn_close,
    _uldn_keyValueDisplayName, _uldn_open, _uloc_canonicalize,
    _uloc_countAvailable, _uloc_getAvailable, _uloc_getBaseName,
    _uloc_getCharacterOrientation, _uloc_getCountry, _uloc_getDefault,
    _uloc_getDisplayCountry, _uloc_getDisplayLanguage, _uloc_getDisplayName,
    _uloc_getISO3Country, _uloc_getISO3Language, _uloc_getKeywordValue,
    _uloc_getLCID, _uloc_getLanguage, _uloc_getName, _uloc_getParent,
    _uloc_setKeywordValue, _ulocdata_getCLDRVersion,
    _ulocdata_getMeasurementSystem, _unorm2_getNFDInstance,
    _unorm2_getNFKCInstance, _unorm2_getNFKDInstance, _unorm2_isNormalized,
    _unum_close, _unum_getAttribute, _unum_getSymbol, _unum_open, _unum_toPattern,
    _ures_close, _ures_getByKey, _ures_getSize, _ures_getStringByIndex,
    _ures_open, _usearch_close, _usearch_first, _usearch_getBreakIterator,
    _usearch_getMatchedLength, _usearch_last, _usearch_openFromCollator,
    _usearch_setPattern, _usearch_setText.

This is what happens:

1. Mono uses ICU for various purposes, and we ship the corresponding helper
   code as a static library (libicui18n.a).
2. iOS also uses ICU, and does so privately, we have no access to iOS’ copy of
   those libraries.
3. FirebaseDatabase links with libicucore.dylib (this is a dylib shipped in
   iOS). I’m not exactly sure why FirebaseDatabase does this, but it seems to
   be allowed by Apple.
4. libicucore.dylib exports some of the symbols from iOS’ (private) copy of
   ICU. I’m assuming this is just an implementation detail on Apple’s side,
   and why they’ve added checks to the App Store to reject any apps that
   reference these private symbols. When using FirebaseDatabase, we end up
   asking the native linker to link with libicucore.dylib (-licucore) due to
   the LinkerFlags in the NativeReference item.
5. We already ask the native linker to link with our own static version of ICU
   (from step 1) – by passing the path to the static library in question
   (libicui18n.a)
6. Depending on which native linker argument comes first (-licucore or
   libicui18n.a) the native linker will find the symbols in one place or the
   other. If found in Apple’s libicucore.dylib, the app ends up rejected by
   the App Store.

So avoid all of this by making FirebaseDatabase not link with
libicucore.dylib.
This commit is contained in:
Rolf Bjarne Kvinge 2023-08-29 15:41:26 +02:00 коммит произвёл GitHub
Родитель 327aa47245
Коммит c7ae591364
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 1 добавлений и 1 удалений

Просмотреть файл

@ -13,7 +13,7 @@
<ItemGroup>
<_NativeReference Update="@(_NativeReference)" Condition="'%(_NativeReference._Id)' == '$(_FirebaseDatabaseId)'">
<Kind>Framework</Kind>
<LinkerFlags>-ObjC -lc++ -licucore</LinkerFlags>
<LinkerFlags>-ObjC -lc++</LinkerFlags>
<Frameworks>CFNetwork Security SystemConfiguration</Frameworks>
<SmartLink>True</SmartLink>
<ForceLoad>True</ForceLoad>