<commit_before>// Copyright 2019 Google
//
// 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 <Foundation/Foundation.h>

#include "Crashlytics/Crashlytics/Handlers/FIRCLSException.h"

#import "Crashlytics/Crashlytics/Private/FIRExceptionModel_Private.h"
#import "Crashlytics/Crashlytics/Private/FIRStackFrame_Private.h"

#include "Crashlytics/Crashlytics/Components/FIRCLSApplication.h"
#include "Crashlytics/Crashlytics/Components/FIRCLSGlobals.h"
#include "Crashlytics/Crashlytics/Components/FIRCLSProcess.h"
#import "Crashlytics/Crashlytics/Components/FIRCLSUserLogging.h"
#include "Crashlytics/Crashlytics/Handlers/FIRCLSHandler.h"
#include "Crashlytics/Crashlytics/Helpers/FIRCLSFile.h"
#import "Crashlytics/Crashlytics/Helpers/FIRCLSLogger.h"
#import "Crashlytics/Crashlytics/Helpers/FIRCLSUtility.h"

#import "Crashlytics/Crashlytics/Controllers/FIRCLSReportManager_Private.h"
#include "Crashlytics/Crashlytics/Operations/Symbolication/FIRCLSDemangleOperation.h"

// C++/Objective-C exception handling
#include <cxxabi.h>
#include <exception>
#include <string>
#include <typeinfo>

#if !TARGET_OS_IPHONE
#import <AppKit/NSApplication.h>
#import <objc/runtime.h>
#endif

#pragma mark Prototypes
static void FIRCLSTerminateHandler(void);
#if !TARGET_OS_IPHONE
void FIRCLSNSApplicationReportException(id self, SEL cmd, NSException *exception);

typedef void (*NSApplicationReportExceptionFunction)(id, SEL, NSException *);

static BOOL FIRCLSIsNSApplicationCrashOnExceptionsEnabled(void);
static NSApplicationReportExceptionFunction FIRCLSOriginalNSExceptionReportExceptionFunction(void);
static Method FIRCLSGetNSApplicationReportExceptionMethod(void);

#endif

#pragma mark - API
void FIRCLSExceptionInitialize(FIRCLSExceptionReadOnlyContext *roContext,
                               FIRCLSExceptionWritableContext *rwContext,
                               void *delegate) {
  if (!FIRCLSUnlinkIfExists(roContext->path)) {
    FIRCLSSDKLog("Unable to reset the exception file %s\n", strerror(errno));
  }

  roContext->originalTerminateHandler = std::set_terminate(FIRCLSTerminateHandler);

#if !TARGET_OS_IPHONE
  // If FIRCLSApplicationSharedInstance is null, we don't need this
  if (FIRCLSIsNSApplicationCrashOnExceptionsEnabled() && FIRCLSApplicationSharedInstance()) {
    Method m = FIRCLSGetNSApplicationReportExceptionMethod();

    roContext->originalNSApplicationReportException =
        (void *)method_setImplementation(m, (IMP)FIRCLSNSApplicationReportException);
  }
#endif

  rwContext->customExceptionCount = 0;
}

void FIRCLSExceptionRecordModel(FIRExceptionModel *exceptionModel) {
  const char *name = [[exceptionModel.name copy] UTF8String];
  const char *reason = [[exceptionModel.reason copy] UTF8String];

  FIRCLSExceptionRecord(FIRCLSExceptionTypeCustom, name, reason, [exceptionModel.stackTrace copy],
                        NO);
}

void FIRCLSExceptionRecordNSException(NSException *exception) {
  FIRCLSSDKLog("Recording an NSException\n");

  NSArray *returnAddresses = [exception callStackReturnAddresses];

  NSString *name = [exception name];
  NSString *reason = [exception reason];

  // It's tempting to try to make use of callStackSymbols here.  But, the output
  // of that function is not intended to be machine-readible.  We could parse it,
  // but that isn't really worthwhile, considering that address-based symbolication
  // needs to work anyways.

  // package our frames up into the appropriate format
  NSMutableArray *frames = [NSMutableArray new];

  for (NSNumber *address in returnAddresses) {
    [frames addObject:[FIRStackFrame stackFrameWithAddress:[address unsignedIntegerValue]]];
  }

  FIRCLSExceptionRecord(FIRCLSExceptionTypeObjectiveC, [name UTF8String], [reason UTF8String],<commit_msg>Fix issue with null reason (#8692)<commit_after>// Copyright 2019 Google
//
// 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 <Foundation/Foundation.h>

#include "Crashlytics/Crashlytics/Handlers/FIRCLSException.h"

#import "Crashlytics/Crashlytics/Private/FIRExceptionModel_Private.h"
#import "Crashlytics/Crashlytics/Private/FIRStackFrame_Private.h"

#include "Crashlytics/Crashlytics/Components/FIRCLSApplication.h"
#include "Crashlytics/Crashlytics/Components/FIRCLSGlobals.h"
#include "Crashlytics/Crashlytics/Components/FIRCLSProcess.h"
#import "Crashlytics/Crashlytics/Components/FIRCLSUserLogging.h"
#include "Crashlytics/Crashlytics/Handlers/FIRCLSHandler.h"
#include "Crashlytics/Crashlytics/Helpers/FIRCLSFile.h"
#import "Crashlytics/Crashlytics/Helpers/FIRCLSLogger.h"
#import "Crashlytics/Crashlytics/Helpers/FIRCLSUtility.h"

#import "Crashlytics/Crashlytics/Controllers/FIRCLSReportManager_Private.h"
#include "Crashlytics/Crashlytics/Operations/Symbolication/FIRCLSDemangleOperation.h"

// C++/Objective-C exception handling
#include <cxxabi.h>
#include <exception>
#include <string>
#include <typeinfo>

#if !TARGET_OS_IPHONE
#import <AppKit/NSApplication.h>
#import <objc/runtime.h>
#endif

#pragma mark Prototypes
static void FIRCLSTerminateHandler(void);
#if !TARGET_OS_IPHONE
void FIRCLSNSApplicationReportException(id self, SEL cmd, NSException *exception);

typedef void (*NSApplicationReportExceptionFunction)(id, SEL, NSException *);

static BOOL FIRCLSIsNSApplicationCrashOnExceptionsEnabled(void);
static NSApplicationReportExceptionFunction FIRCLSOriginalNSExceptionReportExceptionFunction(void);
static Method FIRCLSGetNSApplicationReportExceptionMethod(void);

#endif

#pragma mark - API
void FIRCLSExceptionInitialize(FIRCLSExceptionReadOnlyContext *roContext,
                               FIRCLSExceptionWritableContext *rwContext,
                               void *delegate) {
  if (!FIRCLSUnlinkIfExists(roContext->path)) {
    FIRCLSSDKLog("Unable to reset the exception file %s\n", strerror(errno));
  }

  roContext->originalTerminateHandler = std::set_terminate(FIRCLSTerminateHandler);

#if !TARGET_OS_IPHONE
  // If FIRCLSApplicationSharedInstance is null, we don't need this
  if (FIRCLSIsNSApplicationCrashOnExceptionsEnabled() && FIRCLSApplicationSharedInstance()) {
    Method m = FIRCLSGetNSApplicationReportExceptionMethod();

    roContext->originalNSApplicationReportException =
        (void *)method_setImplementation(m, (IMP)FIRCLSNSApplicationReportException);
  }
#endif

  rwContext->customExceptionCount = 0;
}

void FIRCLSExceptionRecordModel(FIRExceptionModel *exceptionModel) {
  const char *name = [[exceptionModel.name copy] UTF8String];
  const char *reason = [[exceptionModel.reason copy] UTF8String] ?: "";

  FIRCLSExceptionRecord(FIRCLSExceptionTypeCustom, name, reason, [exceptionModel.stackTrace copy],
                        NO);
}

void FIRCLSExceptionRecordNSException(NSException *exception) {
  FIRCLSSDKLog("Recording an NSException\n");

  NSArray *returnAddresses = [exception callStackReturnAddresses];

  NSString *name = [exception name];
  NSString *reason = [exception reason] ?: @"";

  // It's tempting to try to make use of callStackSymbols here.  But, the output
  // of that function is not intended to be machine-readible.  We could parse it,
  // but that isn't really worthwhile, considering that address-based symbolication
  // needs to work anyways.

  // package our frames up into the appropriate format
  NSMutableArray *frames = [NSMutableArray new];

  for (NSNumber *address in returnAddresses) {
    [frames addObject:[FIRStackFrame stackFrameWithAddress:[address unsignedIntegerValue]]];
  }

  FIRCLSExceptionRecord(FIRCLSExceptionTypeObjectiveC, [name UTF8String], [reason UTF8String],
{'fraction_non_alphanumeric': 0.09254079254079255, 'fraction_numerical': 0.0034965034965034965, 'mean_word_length': 5.394187779433681, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5930592', 'n_tokens_mistral': 2720, 'n_tokens_neox': 2574, 'n_words': 618}