Xcode 27.2: `copy_bundle.sh` makes simulator installs fail with `DuplicateIdentifier` (`_Testing_CoreTransferable`), and the 2.0.2 fix has a ksh syntax error

Abierto Apto para principiantes
#178 5 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
shell, swift
Área
devtools

Línea de trabajo

Empieza leyendo copy_bundle.sh, especialmente el bucle de copia de frameworks y la condición añadida en 2.0.2; la incidencia identifica al intérprete ksh del sistema como origen del error de sintaxis. Comprueba el manejo de los identificadores de bundle con los frameworks duplicados _Testing_CoreTransferable y _Testing_CoreGraphics; después, ejecuta ksh -n copy_bundle.sh. El objetivo es que el script se analice correctamente y evite copiar frameworks con un identificador de bundle duplicado, manteniendo las demás copias necesarias.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Summary

On Xcode 27.2, any app that runs copy_bundle.sh in a build phase can't be installed on the simulator any more. The script copies every _Testing_*.framework from the platform's developer Frameworks folder into the app. In Xcode 27.2, _Testing_CoreTransferable.framework has the same CFBundleIdentifier as _Testing_CoreGraphics.framework, so installd rejects the app with MIInstallerErrorDomain code 57 (DuplicateIdentifier).

2.0.2 tries to skip the Transferable framework, but the new condition doesn't parse in ksh. That's the script's interpreter (#!/bin/ksh -x), so the whole script now fails with a syntax error.

Environment

InjectionNext 2.0.1 (the bug); 2.0.2, build 14919 (the syntax error)
Xcode 27.2 (27B52)
Simulator runtime iOS 27.2 (24B8117), iPhone19,2
macOS 27.2.1 (26B131)
ksh sh (AT&T Research) 93u+ 2012-08-01 (the system /bin/ksh)

Root cause

Xcode 27.2 ships _Testing_CoreTransferable.framework with the wrong bundle identifier. The framework's code signature is valid, so this is how Apple ships it:

$ F=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks
$ /usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' "$F/_Testing_CoreGraphics.framework/Info.plist"
com.apple.dt.swift-testing.overlay.CoreGraphics
$ /usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' "$F/_Testing_CoreTransferable.framework/Info.plist"
com.apple.dt.swift-testing.overlay.CoreGraphics      <-- should be ...overlay.CoreTransferable
$ codesign --verify --strict -v "$F/_Testing_CoreTransferable.framework"
... valid on disk
... satisfies its Designated Requirement

(The Info.plist of _Testing_CoreTransferable.framework reports DTXcodeBuild = 27B49.)

Xcode normally puts these overlays only into test bundles, so plain app builds never hit this. copy_bundle.sh copies them into the app's Frameworks folder:

(cd "$PRODUCTS_DIR" && for fwork in $TESTING_FRAMEWORKS \
    "$PLATFORM_DEVELOPER_LIBRARY_DIR"/Frameworks/_Testing_*.framework; do
    TESTING_COPIED="$CODESIGNING_FOLDER_PATH/Frameworks/$(basename "$fwork")"
    if [ -f "$fwork/Info.plist" -a ! -d "$TESTING_COPIED" ]; then
        rsync -a "$fwork" "$CODESIGNING_FOLDER_PATH/Frameworks" && codesign ...

With both frameworks in MyApp.app/Frameworks, the simulator install fails in -[MIInstallableBundle performPreflightWithError:].

The 2.0.2 change doesn't parse

2.0.2 changes the condition to:

if [ -f "$fwork/Info.plist" -a ! -d "$TESTING_COPIED" -a ! ( "$fwork" =~ Transferable ) ]; then

[ (test) supports neither =~ nor unescaped (, so ksh rejects the script before it runs:

$ ksh -n /Applications/InjectionNext.app/Contents/Resources/copy_bundle.sh
/Applications/InjectionNext.app/Contents/Resources/copy_bundle.sh: syntax error at line 63: `(' unexpected
$ echo $?
3

So with 2.0.2 the copy phase fails outright: nothing is copied, including iOSInjection.bundle, and the run-script phase exits non-zero.

Steps to reproduce

  1. Install Xcode 27.2 (27B52) and InjectionNext 2.0.1.
  2. Add the usual run-script phase to an iOS app target:
    export RESOURCES="/Applications/InjectionNext.app/Contents/Resources"
    if [ -f "$RESOURCES/copy_bundle.sh" ]; then
        "$RESOURCES/copy_bundle.sh"
    fi
    
  3. Build and run the Debug configuration on an iOS 27.2 simulator.
  4. 2.0.1: the build succeeds, but the install fails with the error below. 2.0.2: the run-script phase fails with the ksh syntax error.

Expected

The app installs and runs, with the testing frameworks InjectionNext needs copied in, and the script skips (or de-duplicates) the framework whose bundle ID clashes.

Actual (2.0.1), redacted

App installation failed: Unable to Install "MyApp"
Domain: IXUserPresentableErrorDomain
Code: 1
Failure Reason: Please try again later.
Recovery Suggestion: Found bundle at /Users/<user>/Library/Developer/CoreSimulator/Devices/<SIMULATOR-UDID>/data/Library/Caches/com.apple.mobile.installd.staging/temp.<id>/extracted/MyApp.app/Frameworks/_Testing_CoreGraphics.framework with the same identifier (com.apple.dt.swift-testing.overlay.CoreGraphics) as bundle at /Users/<user>/Library/Developer/CoreSimulator/Devices/<SIMULATOR-UDID>/data/Library/Caches/com.apple.mobile.installd.staging/temp.<id>/extracted/MyApp.app/Frameworks/_Testing_CoreTransferable.framework
User Info: {
    IDERunOperationFailingWorker = IDELaunchiPhoneSimulatorLauncher;
    SimCallingSelector = "installApplication:withOptions:installationInfo:error:";
}
--
Found bundle at .../MyApp.app/Frameworks/_Testing_CoreGraphics.framework with the same identifier (com.apple.dt.swift-testing.overlay.CoreGraphics) as bundle at .../MyApp.app/Frameworks/_Testing_CoreTransferable.framework
Domain: MIInstallerErrorDomain
Code: 57
User Info: {
    FunctionName = "-[MIInstallableBundle performPreflightWithError:]";
    LegacyErrorString = DuplicateIdentifier;
    SourceFileLine = 628;
}
--
Event Metadata: com.apple.dt.IDERunOperationWorkerFinished : {
    "device_model" = "iPhone19,2";
    "device_osBuild" = "27.2 (24B8117)";
    "device_platform" = "com.apple.platform.iphonesimulator";
    "launchSession_schemeCommand" = Run;
    "launchSession_targetArch" = arm64;
    "operation_errorCode" = 1;
    "operation_errorDomain" = IXUserPresentableErrorDomain;
    "operation_errorWorker" = IDELaunchiPhoneSimulatorLauncher;
    "param_runnable_productType" = "com.apple.product-type.application";
    "param_testing_launchedForTesting" = 0;
    "sdk_canonicalName" = "iphonesimulator27.2";
}

System Information
macOS Version 27.2.1 (Build 26B131)
Xcode 27.2 (25400.63.5) (Build 27B52)

Suggested fix

Replace the [ ... ( =~ ) ] test with something ksh accepts. For example, skip by name:

(cd "$PRODUCTS_DIR" && for fwork in $TESTING_FRAMEWORKS \
    "$PLATFORM_DEVELOPER_LIBRARY_DIR"/Frameworks/_Testing_*.framework; do
    case "$fwork" in *_Testing_CoreTransferable.framework) continue;; esac
    TESTING_COPIED="$CODESIGNING_FOLDER_PATH/Frameworks/$(basename "$fwork")"
    if [ -f "$fwork/Info.plist" -a ! -d "$TESTING_COPIED" ]; then
        ...

A sturdier fix wouldn't depend on a framework's name, so it keeps working once Apple fixes the plist or another overlay gets the same problem. It would skip any framework whose CFBundleIdentifier is already in the app:

SEEN_IDS=""
(cd "$PRODUCTS_DIR" && for fwork in $TESTING_FRAMEWORKS \
    "$PLATFORM_DEVELOPER_LIBRARY_DIR"/Frameworks/_Testing_*.framework; do
    [ -f "$fwork/Info.plist" ] || continue
    ID=$(/usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' "$fwork/Info.plist" 2>/dev/null)
    case " $SEEN_IDS " in *" $ID "*) echo "Skipping $fwork: duplicate bundle id $ID"; continue;; esac
    SEEN_IDS="$SEEN_IDS $ID"
    TESTING_COPIED="$CODESIGNING_FOLDER_PATH/Frameworks/$(basename "$fwork")"
    if [ ! -d "$TESTING_COPIED" ]; then
        ...

Running ksh -n copy_bundle.sh in CI or before a release would also catch syntax errors like this one.

Workaround for users

Until a fixed release ships, either quit InjectionNext and move it out of /Applications, or delete the copied _Testing_CoreTransferable.framework from the built app before it's installed. Then do a Clean Build Folder (⇧⌘K) once, because frameworks already copied into the app stay there until you clean.

Lenguaje dominante
Swift
Estrellas
443
Forks
31
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de johnno1962/InjectionNext

Todos los issues de johnno1962/InjectionNext

Issues similares

Más issues de Swift

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.