// Copyright 2020 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import <XCTest/XCTest.h>
#include <objc/runtime.h>
#include <sys/sysctl.h>

#include <vector>

#import "Service/Sources/EDOClientService.h"
#include "build/build_config.h"
#include "client/length_delimited_ring_buffer.h"
#import "test/ios/host/cptest_shared_object.h"
#include "util/mach/exception_types.h"
#include "util/mach/mach_extensions.h"

namespace {

#if TARGET_OS_SIMULATOR
// macOS 14.0 is 23A344, macOS 13.6.5 is 22G621, so if the first two characters
// in the kern.osversion are > 22, this build will reproduce the simulator bug
// in crbug.com/328282286
bool IsMacOSVersion143OrGreaterAndiOS16OrLess() {
  if (__builtin_available(iOS 17, *)) {
    return false;
  }

  size_t buf_len;
  static constexpr char name[] = "kern.osversion";
  if (sysctlbyname(name, nullptr, &buf_len, nullptr, 0) != 0) {
    return false;
  }

  std::string build(buf_len - 1, '\0');
  if (sysctlbyname(name, &build[0], &buf_len, nullptr, 0) != 0) {
    return false;
  }

  return std::stoi(build.substr(0, 2)) > 22;
}
#endif

}  // namespace

@interface CPTestTestCase : XCTestCase {
  XCUIApplication* app_;
  CPTestSharedObject* rootObject_;
}
@end

@implementation CPTestTestCase

+ (void)setUp {
  [CPTestTestCase swizzleHandleCrashUnderSymbol];
  [CPTestTestCase swizleMayTerminateOutOfBandWithoutCrashReport];

  // Override EDO default error handler.  Without this, the default EDO error
  // handler will throw an error and fail the test.
  EDOSetClientErrorHandler(^(NSError* error){
      // Do nothing.
  });
}

// Swizzle away the -[XCUIApplicationImpl handleCrashUnderSymbol:] callback.
// Without this, any time the host app is intentionally crashed, the test is
// immediately failed.
+ (void)swizzleHandleCrashUnderSymbol {
  SEL originalSelector = NSSelectorFromString(@"handleCrashUnderSymbol:");
  SEL swizzledSelector = @selector(handleCrashUnderSymbol:);
  Method originalMethod = class_getInstanceMethod(
      objc_getClass("XCUIApplicationImpl"), originalSelector);
  Method swizzledMethod =
      class_getInstanceMethod([self class], swizzledSelector);
  method_exchangeImplementations(originalMethod, swizzledMethod);
}

// Swizzle away the time consuming 'Checking for crash reports corresponding to'
// from -[XCUIApplicationProcess swizleMayTerminateOutOfBandWithoutCrashReport]
// that is unnecessary for these tests.
+ (void)swizleMayTerminateOutOfBandWithoutCrashReport {
  SEL originalSelector =
      NSSelectorFromString(@"mayTerminateOutOfBandWithoutCrashReport");
  SEL swizzledSelector = @selector(mayTerminateOutOfBandWithoutCrashReport);
  Method originalMethod = class_getInstanceMethod(
      objc_getClass("XCUIApplicationProcess"), originalSelector);
  Method swizzledMethod =
      class_getInstanceMethod([self class], swizzledSelector);
  method_exchangeImplementations(originalMethod, swizzledMethod);
}

// This gets called after tearDown, so there's no straightforward way to
// test that this is called. However, not swizzling this out will cause every
// crashing test to fail.
- (void)handleCrashUnderSymbol:(id)arg1 {
}

- (BOOL)mayTerminateOutOfBandWithoutCrashReport {
  return YES;
}

- (void)setUp {
  app_ = [[XCUIApplication alloc] init];
  [app_ launch];
  rootObject_ = [EDOClientService rootObjectWithPort:12345];
  [rootObject_ clearPendingReports];
  XCTAssertEqual([rootObject_ pendingReportCount], 0);
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);
}

- (void)verifyCrashReportException:(uint32_t)exception {
  // Confirm the app is not running.
  XCTAssertTrue([app_ waitForState:XCUIApplicationStateNotRunning timeout:15]);
  XCTAssertTrue(app_.state == XCUIApplicationStateNotRunning);

  // Restart app to get the report signal.
  [app_ launch];
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);
  rootObject_ = [EDOClientService rootObjectWithPort:12345];
  XCTAssertEqual([rootObject_ pendingReportCount], 1);
  NSNumber* report_exception;
  XCTAssertTrue([rootObject_ pendingReportException:&report_exception]);
  XCTAssertEqual(report_exception.unsignedIntValue, exception);

  NSString* rawLogContents = [rootObject_ rawLogContents];
  XCTAssertFalse([rawLogContents containsString:@"allocator used in handler."]);
}

- (void)testEDO {
  NSString* result = [rootObject_ testEDO];
  XCTAssertEqualObjects(result, @"crashpad");
}

- (void)testKillAbort {
  [rootObject_ crashKillAbort];
  [self verifyCrashReportException:EXC_SOFT_SIGNAL];
  NSNumber* report_exception;
  XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]);
  XCTAssertEqual(report_exception.intValue, SIGABRT);
}

- (void)testTrap {
  [rootObject_ crashTrap];
#if defined(ARCH_CPU_X86_64)
  [self verifyCrashReportException:EXC_BAD_INSTRUCTION];
#elif defined(ARCH_CPU_ARM64)
  [self verifyCrashReportException:EXC_BREAKPOINT];
#else
#error Port to your CPU architecture
#endif
}

- (void)testAbort {
  [rootObject_ crashAbort];
  [self verifyCrashReportException:EXC_SOFT_SIGNAL];
  NSNumber* report_exception;
  XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]);
  XCTAssertEqual(report_exception.intValue, SIGABRT);
}

- (void)testBadAccess {
  [rootObject_ crashBadAccess];
  [self verifyCrashReportException:EXC_BAD_ACCESS];
}

- (void)testException {
  [rootObject_ crashException];
  // After https://reviews.llvm.org/D141222 exceptions call
  // __libcpp_verbose_abort, which Chromium sets to `brk 0` in release.
  // After https://crrev.com/c/5375084, Chromium does not set `brk 0` for local
  // release builds and official DCHECK builds.
#if defined(CRASHPAD_IS_IN_CHROMIUM) && defined(NDEBUG) && \
    defined(OFFICIAL_BUILD) && !defined(DCHECK_ALWAYS_ON)
  [self verifyCrashReportException:SIGABRT];
#else
  [self verifyCrashReportException:EXC_SOFT_SIGNAL];
  NSNumber* report_exception;
  XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]);
  XCTAssertEqual(report_exception.intValue, SIGABRT);
#endif
}

- (void)testNSException {
  [rootObject_ crashNSException];
  [self verifyCrashReportException:crashpad::kMachExceptionFromNSException];
  NSDictionary* dict = [rootObject_ getAnnotations];
  NSString* userInfo =
      [dict[@"objects"][0] valueForKeyPath:@"exceptionUserInfo"];
  XCTAssertTrue([userInfo containsString:@"Error Object=<CPTestSharedObject"]);
  XCTAssertTrue([[dict[@"objects"][1] valueForKeyPath:@"exceptionReason"]
      isEqualToString:@"Intentionally throwing error."]);
  XCTAssertTrue([[dict[@"objects"][2] valueForKeyPath:@"exceptionName"]
      isEqualToString:@"NSInternalInconsistencyException"]);
}

- (void)testNotAnNSException {
  [rootObject_ crashNotAnNSException];
  // When @throwing something other than an NSException the
  // UncaughtExceptionHandler is not called, so the application SIGABRTs.
  [self verifyCrashReportException:EXC_SOFT_SIGNAL];
  NSNumber* report_exception;
  XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]);
  XCTAssertEqual(report_exception.intValue, SIGABRT);
}

- (void)testUnhandledNSException {
  [rootObject_ crashUnhandledNSException];
  [self verifyCrashReportException:crashpad::kMachExceptionFromNSException];
  NSDictionary* dict = [rootObject_ getAnnotations];
  NSString* uncaught_flag =
      [dict[@"objects"][0] valueForKeyPath:@"UncaughtNSException"];
  XCTAssertTrue([uncaught_flag containsString:@"true"]);
  NSString* userInfo =
      [dict[@"objects"][1] valueForKeyPath:@"exceptionUserInfo"];
  XCTAssertTrue([userInfo containsString:@"Error Object=<CPTestSharedObject"]);
  XCTAssertTrue([[dict[@"objects"][2] valueForKeyPath:@"exceptionReason"]
      isEqualToString:@"Intentionally throwing error."]);
  XCTAssertTrue([[dict[@"objects"][3] valueForKeyPath:@"exceptionName"]
      isEqualToString:@"NSInternalInconsistencyException"]);
}

- (void)testcrashUnrecognizedSelectorAfterDelay {
  [rootObject_ crashUnrecognizedSelectorAfterDelay];
  [self verifyCrashReportException:crashpad::kMachExceptionFromNSException];
  NSDictionary* dict = [rootObject_ getAnnotations];
  XCTAssertTrue([[dict[@"objects"][0] valueForKeyPath:@"exceptionReason"]
      containsString:
          @"CPTestSharedObject does_not_exist]: unrecognized selector"]);
  XCTAssertTrue([[dict[@"objects"][1] valueForKeyPath:@"exceptionName"]
      isEqualToString:@"NSInvalidArgumentException"]);
}

- (void)testCatchUIGestureEnvironmentNSException {
  // Tap the button with the string UIGestureEnvironmentException.
  [app_.buttons[@"UIGestureEnvironmentException"] tap];
  [self verifyCrashReportException:crashpad::kMachExceptionFromNSException];
  NSDictionary* dict = [rootObject_ getAnnotations];
  XCTAssertTrue([[dict[@"objects"][0] valueForKeyPath:@"exceptionReason"]
      containsString:@"NSArray0 objectAtIndex:]: index 42 beyond bounds"]);
  XCTAssertTrue([[dict[@"objects"][1] valueForKeyPath:@"exceptionName"]
      isEqualToString:@"NSRangeException"]);
}

- (void)testCatchNSException {
  [rootObject_ catchNSException];

  // The app should not crash
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);

  // No report should be generated.
  [rootObject_ processIntermediateDumps];
  XCTAssertEqual([rootObject_ pendingReportCount], 0);
}

- (void)testCrashCoreAutoLayoutSinkhole {
  [rootObject_ crashCoreAutoLayoutSinkhole];
  [self verifyCrashReportException:crashpad::kMachExceptionFromNSException];
  NSDictionary* dict = [rootObject_ getAnnotations];
  XCTAssertTrue([[dict[@"objects"][0] valueForKeyPath:@"exceptionReason"]
      containsString:@"Unable to activate constraint with anchors"]);
  XCTAssertTrue([[dict[@"objects"][1] valueForKeyPath:@"exceptionName"]
      isEqualToString:@"NSGenericException"]);
}

- (void)testRecursion {
  [rootObject_ crashRecursion];
  [self verifyCrashReportException:EXC_BAD_ACCESS];
}

- (void)testClientAnnotations {
  [rootObject_ crashKillAbort];

  // Set app launch args to trigger different client annotations.
  NSArray<NSString*>* old_args = app_.launchArguments;
  app_.launchArguments = @[ @"--alternate-client-annotations" ];
  [self verifyCrashReportException:EXC_SOFT_SIGNAL];
  NSNumber* report_exception;
  XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]);
  XCTAssertEqual(report_exception.intValue, SIGABRT);

  app_.launchArguments = old_args;

  // Confirm the initial crash took the standard annotations.
  NSDictionary* dict = [rootObject_ getProcessAnnotations];
  XCTAssertTrue([dict[@"crashpad"] isEqualToString:@"yes"]);
  XCTAssertTrue([dict[@"plat"] isEqualToString:@"iOS"]);
  XCTAssertTrue([dict[@"prod"] isEqualToString:@"xcuitest"]);
  XCTAssertTrue([dict[@"ver"] isEqualToString:@"1"]);

  // Confirm passing alternate client annotation args works.
  [rootObject_ clearPendingReports];
  [rootObject_ crashKillAbort];
  [self verifyCrashReportException:EXC_SOFT_SIGNAL];
  XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]);
  XCTAssertEqual(report_exception.intValue, SIGABRT);

  dict = [rootObject_ getProcessAnnotations];
  XCTAssertTrue([dict[@"crashpad"] isEqualToString:@"no"]);
  XCTAssertTrue([dict[@"plat"] isEqualToString:@"macOS"]);
  XCTAssertTrue([dict[@"prod"] isEqualToString:@"some_app"]);
  XCTAssertTrue([dict[@"ver"] isEqualToString:@"42"]);
}

#if TARGET_OS_SIMULATOR
- (void)testCrashWithCrashInfoMessage {
  if (@available(iOS 15.0, *)) {
    // Figure out how to test this on iOS15.
    return;
  }
  [rootObject_ crashWithCrashInfoMessage];
  [self verifyCrashReportException:EXC_BAD_ACCESS];
  NSDictionary* dict = [rootObject_ getAnnotations];
  NSString* dyldMessage = dict[@"vector"][0];
  XCTAssertTrue([dyldMessage isEqualToString:@"dyld: in dlsym()"]);
}
#endif

// TODO(justincohen): Codesign crashy_initializer.so so it can run on devices.
#if TARGET_OS_SIMULATOR
- (void)testCrashWithDyldErrorString {
  if (@available(iOS 15.0, *)) {
    // iOS 15 uses dyld4, which doesn't use CRSetCrashLogMessage2
    return;
  }
  [rootObject_ crashWithDyldErrorString];
#if defined(ARCH_CPU_X86_64)
  [self verifyCrashReportException:EXC_BAD_INSTRUCTION];
#elif defined(ARCH_CPU_ARM64)
  [self verifyCrashReportException:EXC_BREAKPOINT];
#else
#error Port to your CPU architecture
#endif
  NSArray* vector = [rootObject_ getAnnotations][@"vector"];
  // This message is set by dyld-353.2.1/src/ImageLoaderMachO.cpp
  // ImageLoaderMachO::doInitialization().
  NSString* module = @"crashpad_snapshot_test_module_crashy_initializer.so";
  XCTAssertTrue([vector[0] hasSuffix:module]);
}
#endif

- (void)testCrashWithAnnotations {
#if TARGET_OS_SIMULATOR
  // This test will fail on older (<iOS17 simulators) when running on macOS 14.3
  // or newer due to a bug in Simulator. crbug.com/328282286
  if (IsMacOSVersion143OrGreaterAndiOS16OrLess()) {
    return;
  }
#endif

  [rootObject_ crashWithAnnotations];
  [self verifyCrashReportException:EXC_SOFT_SIGNAL];
  NSNumber* report_exception;
  XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]);
  XCTAssertEqual(report_exception.intValue, SIGABRT);

  NSDictionary* dict = [rootObject_ getAnnotations];
  NSDictionary* simpleMap = dict[@"simplemap"];
  XCTAssertTrue([simpleMap[@"#TEST# empty_value"] isEqualToString:@""]);
  XCTAssertTrue([simpleMap[@"#TEST# key"] isEqualToString:@"value"]);
  XCTAssertTrue([simpleMap[@"#TEST# longer"] isEqualToString:@"shorter"]);
  XCTAssertTrue([simpleMap[@"#TEST# pad"] isEqualToString:@"crash"]);
  XCTAssertTrue([simpleMap[@"#TEST# x"] isEqualToString:@"y"]);

  XCTAssertTrue([[dict[@"objects"][0] valueForKeyPath:@"#TEST# same-name"]
      isEqualToString:@"same-name 4"]);
  XCTAssertTrue([[dict[@"objects"][1] valueForKeyPath:@"#TEST# same-name"]
      isEqualToString:@"same-name 3"]);
  XCTAssertTrue([[dict[@"objects"][2] valueForKeyPath:@"#TEST# one"]
      isEqualToString:@"moocow"]);
  // Ensure `ring_buffer` is present but not `busy_ring_buffer`.
  XCTAssertEqual(1u, [dict[@"ringbuffers"] count]);
  NSData* ringBufferNSData =
      [dict[@"ringbuffers"][0] valueForKeyPath:@"#TEST# ring_buffer"];
  crashpad::RingBufferData ringBufferData;
  XCTAssertTrue(ringBufferData.DeserializeFromBuffer(ringBufferNSData.bytes,
                                                     ringBufferNSData.length));
  crashpad::LengthDelimitedRingBufferReader reader(ringBufferData);

  std::vector<uint8_t> ringBufferEntry;
  XCTAssertTrue(reader.Pop(ringBufferEntry));
  NSString* firstEntry = [[NSString alloc] initWithBytes:ringBufferEntry.data()
                                                  length:ringBufferEntry.size()
                                                encoding:NSUTF8StringEncoding];
  XCTAssertEqualObjects(firstEntry, @"hello");
  ringBufferEntry.clear();

  XCTAssertTrue(reader.Pop(ringBufferEntry));
  NSString* secondEntry = [[NSString alloc] initWithBytes:ringBufferEntry.data()
                                                   length:ringBufferEntry.size()
                                                 encoding:NSUTF8StringEncoding];
  XCTAssertEqualObjects(secondEntry, @"goodbye");
  ringBufferEntry.clear();

  XCTAssertFalse(reader.Pop(ringBufferEntry));
}

- (void)testDumpWithoutCrash {
  [rootObject_ generateDumpWithoutCrash:10 threads:3];

  // The app should not crash
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);

  XCTAssertEqual([rootObject_ pendingReportCount], 30);
}

- (void)testSimultaneousCrash {
  [rootObject_ crashConcurrentSignalAndMach];

  // Confirm the app is not running.
  XCTAssertTrue([app_ waitForState:XCUIApplicationStateNotRunning timeout:15]);
  XCTAssertTrue(app_.state == XCUIApplicationStateNotRunning);

  [app_ launch];
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);
  rootObject_ = [EDOClientService rootObjectWithPort:12345];
  XCTAssertEqual([rootObject_ pendingReportCount], 1);
}

- (void)testSimultaneousNSException {
  [rootObject_ catchConcurrentNSException];

  // The app should not crash
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);

  // No report should be generated.
  [rootObject_ processIntermediateDumps];
  XCTAssertEqual([rootObject_ pendingReportCount], 0);
}

- (void)testCrashInHandlerReentrant {
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);
  rootObject_ = [EDOClientService rootObjectWithPort:12345];

  [rootObject_ crashInHandlerReentrant];

  // Confirm the app is not running.
  XCTAssertTrue([app_ waitForState:XCUIApplicationStateNotRunning timeout:15]);
  XCTAssertTrue(app_.state == XCUIApplicationStateNotRunning);

  [app_ launch];
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);
  rootObject_ = [EDOClientService rootObjectWithPort:12345];

  XCTAssertEqual([rootObject_ pendingReportCount], 0);

  NSString* rawLogContents = [rootObject_ rawLogContents];
  NSString* errmsg = @"Cannot DumpExceptionFromSignal without writer";
  XCTAssertTrue([rawLogContents containsString:errmsg]);
}

- (void)testFailureWhenHandlerAllocates {
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);
  rootObject_ = [EDOClientService rootObjectWithPort:12345];

  [rootObject_ allocateWithForbiddenAllocators];

  // Confirm the app is not running.
  XCTAssertTrue([app_ waitForState:XCUIApplicationStateNotRunning timeout:15]);
  XCTAssertTrue(app_.state == XCUIApplicationStateNotRunning);

  [app_ launch];
  XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);
  rootObject_ = [EDOClientService rootObjectWithPort:12345];

  XCTAssertEqual([rootObject_ pendingReportCount], 0);

  NSString* rawLogContents = [rootObject_ rawLogContents];
  XCTAssertTrue([rawLogContents containsString:@"allocator used in handler."]);
}

@end
