Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ios_system.m
Original file line number Diff line number Diff line change
Expand Up @@ -3249,6 +3249,7 @@ int ios_system(const char* inputCmd) {
ios_startInteractive();
}
// NSLog(@"command after alias expansion= %s\n", command);
maxPointer = command + strlen(command);
// Search for input, output and error redirection
// They can be in any order, although the usual are:
// command < input > output 2> error, command < input > output 2>&1 or command < input >& output
Expand Down
18 changes: 18 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,24 @@ xcrun simctl spawn "$SIMULATOR_UDID" "$PWD/.build/child-status/child-status"

Expected: exit 0 and `child A expected=7 observed=7; child B expected=23 observed=23: PASS`, `missing command expected=127 observed=127` and `empty command expected=0 observed=0; NULL command expected=0 observed=0`. With shared session status, both children report 23 and the test exits 1. A ten-second alarm bounds a stalled wait. This fixture covers a normal return, `ios_exit` and commands that do not start; it does not qualify cancellation, thread-creation failure or PID reuse.

# Redirected alias

`alias-redirection.m` defines an alias for a registered command with two arguments, then runs the alias with stdout and stderr redirected to files. The command must receive both arguments and return 7, and each file must hold exactly the line written to it. The expanded command is always a new allocation, and whether the stale bound is exceeded depends on where malloc places it. The alias pads its arguments with 2048 spaces: without the padding the test passed before the fix, with it the abort reproduced in three runs out of three.

From the repository root, build and run on an explicitly selected booted Simulator:

```sh
xcodebuild -project ios_system.xcodeproj -target ios_system -configuration Release -sdk iphonesimulator -jobs 2 ARCHS=arm64 CODE_SIGNING_ALLOWED=NO IPHONEOS_DEPLOYMENT_TARGET=15.0 CONFIGURATION_BUILD_DIR="$PWD/.build/alias-redirection-sdk" OBJROOT="$PWD/.build/alias-redirection-obj" build
mkdir -p .build/alias-redirection/Frameworks .build/alias-redirection/results
cp -R .build/alias-redirection-sdk/ios_system.framework .build/alias-redirection/Frameworks/
cp Resources/commandDictionary.plist .build/alias-redirection/
xcrun --sdk iphonesimulator clang -target arm64-apple-ios15.0-simulator -isysroot "$(xcrun --sdk iphonesimulator --show-sdk-path)" -fobjc-arc -Wall -Wextra -Wno-unused-parameter -I ios_system -F .build/alias-redirection/Frameworks -framework ios_system -framework Foundation -Wl,-rpath,@executable_path/Frameworks -Wl,-export_dynamic tests/alias-redirection.m -o .build/alias-redirection/alias-redirection
codesign --force --sign - .build/alias-redirection/Frameworks/ios_system.framework
codesign --force --sign - .build/alias-redirection/alias-redirection
xcrun simctl spawn "$SIMULATOR_UDID" "$PWD/.build/alias-redirection/alias-redirection" "$PWD/.build/alias-redirection/results"
```

Expected: exit 0 and `redirected alias: status=7 stdout=exact stderr=exact PASS`. Before the fix, the bound checked by `assert(endFile <= maxPointer)` still pointed at the end of the freed original command, and the run aborted with signal 6.
# Captured less output

`less-capture.m` runs the bundled `less` through the public session API with native terminal detection and non-terminal output. It requires status zero and exactly the input bytes, for a file and a pipe, twice in the same process. The unpatched command appends an escape sequence that moves the cursor to the last screen row. The ten-second watchdog exits 124 on a hang.
Expand Down
43 changes: 43 additions & 0 deletions tests/alias-redirection.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#import <Foundation/Foundation.h>
#import "ios_system.h"
#include <signal.h>
#include <unistd.h>

int alias_output_main(int argc, char **argv) {
if (argc != 3 || strcmp(argv[1], "alpha") || strcmp(argv[2], "beta")) return 99;
fputs("OUT alpha beta\n", thread_stdout);
fputs("ERR alpha beta\n", thread_stderr);
return 7;
}

static void timedOut(int number) { _Exit(124); }

int main(int argc, char **argv) {
@autoreleasepool {
if (argc != 2) return 2;
signal(SIGALRM, timedOut);
alarm(10);
NSString *directory = [NSString stringWithUTF8String:argv[1]];
if (![[NSFileManager defaultManager] changeCurrentDirectoryPath:directory]) return 2;
initializeEnvironment();
ios_switchSession("alias-redirection");
ios_setStreams(stdin, stdout, stderr);
joinMainThread = true;
replaceCommand(@"alias-output", @"alias_output_main", false);
// Without the padding the stale bound was not exceeded before the fix; with it the abort reproduced in three runs out of three.
NSString *alias = [NSString stringWithFormat:@"alias redirected 'alias-output alpha%@beta'",
[@"" stringByPaddingToLength:2048 withString:@" " startingAtIndex:0]];
if (ios_system(alias.UTF8String)) return 2;
unlink("stdout.txt");
unlink("stderr.txt");
int status = ios_system("redirected > stdout.txt 2> stderr.txt");
NSString *output = [NSString stringWithContentsOfFile:@"stdout.txt" encoding:NSUTF8StringEncoding error:nil];
NSString *error = [NSString stringWithContentsOfFile:@"stderr.txt" encoding:NSUTF8StringEncoding error:nil];
BOOL passed = status == 7 && [output isEqualToString:@"OUT alpha beta\n"] && [error isEqualToString:@"ERR alpha beta\n"];
dprintf(STDERR_FILENO, "redirected alias: status=%d stdout=%s stderr=%s %s\n", status,
[output isEqualToString:@"OUT alpha beta\n"] ? "exact" : "FAIL",
[error isEqualToString:@"ERR alpha beta\n"] ? "exact" : "FAIL", passed ? "PASS" : "FAIL");
alarm(0);
return passed ? 0 : 1;
}
}
Loading