Skip to content
This repository was archived by the owner on Jun 2, 2018. It is now read-only.

UIEditUserWordController causes A2DynamicDelegate crash #355

Open

Description

@pengan1987

This issue may same to #283
Procedure to reproduce this issue:

Add any Chinese/Japanese characters in an UITextField
Select the characters entered
In the popup menu, select [Learn...]
A "Text Replacement" view pops up
Click "Cancel" in top left corner
Then the app crashes

img_0604_result

The position of error:

UITextField+BlocksKit.m, line 23

//At this time, the realDelegate is an UIEditUserWordController
//which only used in asian language service
ret = [realDelegate textFieldShouldBeginEditing:textField];

A2DynamicDelegate.m, line 159

//The self.realDelegate is an pointer points to unreadable memory, then app crash
return [self.invocationsBySelectors bk_objectForSelector:selector] || class_respondsToSelector(object_getClass(self), selector) || [self.realDelegate respondsToSelector:selector];

Activity

  1. littleSun commented on Nov 28, 2016

    @littleSun

    //
    // UITextField+BlocksKit.m
    // BlocksKit
    //

    #import "UITextField+BlocksKit.h"
    #import "A2DynamicDelegate.h"
    #import "NSObject+A2BlockDelegate.h"

    #pragma mark Delegate

    @interface A2DynamicUITextFieldDelegate : A2DynamicDelegate

    @EnD

    @implementation A2DynamicUITextFieldDelegate

    • (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
      {
      BOOL ret = YES;

      id realDelegate = self.realDelegate;

      if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
      return ret;
      }

      if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldShouldBeginEditing:)])
      ret = [realDelegate textFieldShouldBeginEditing:textField];
      BOOL (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
      if (block)
      ret &= block(textField);
      return ret;
      }

    • (void)textFieldDidBeginEditing:(UITextField *)textField
      {
      id realDelegate = self.realDelegate;

      if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
      return;
      }

      if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldDidBeginEditing:)])
      [realDelegate textFieldDidBeginEditing:textField];
      void (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
      if (block)
      block(textField);
      }

    • (BOOL)textFieldShouldEndEditing:(UITextField *)textField
      {
      BOOL ret = YES;
      id realDelegate = self.realDelegate;

      if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
      return ret;
      }

      if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldShouldEndEditing:)])
      ret = [realDelegate textFieldShouldEndEditing:textField];
      BOOL (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
      if (block)
      ret &= block(textField);
      return ret;
      }

    • (void)textFieldDidEndEditing:(UITextField *)textField
      {
      id realDelegate = self.realDelegate;

      if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
      return;
      }

      if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldDidEndEditing:)])
      [realDelegate textFieldDidEndEditing:textField];
      void (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
      if (block)
      block(textField);
      }

    • (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
      {
      BOOL ret = YES;
      id realDelegate = self.realDelegate;

      if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
      return ret;
      }

      if (realDelegate && [realDelegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)])
      ret = [realDelegate textField:textField shouldChangeCharactersInRange:range replacementString:string];
      BOOL (^block)(UITextField *, NSRange, NSString *) = [self blockImplementationForMethod:_cmd];
      if (block)
      ret &= block(textField, range, string);
      return ret;
      }

    • (BOOL)textFieldShouldClear:(UITextField *)textField
      {
      BOOL ret = YES;
      id realDelegate = self.realDelegate;

      if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
      return ret;
      }

      if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldShouldClear:)])
      ret = [realDelegate textFieldShouldClear:textField];
      BOOL (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
      if (block)
      ret &= block(textField);
      return ret;
      }

    • (BOOL)textFieldShouldReturn:(UITextField *)textField
      {
      BOOL ret = YES;
      id realDelegate = self.realDelegate;

      if (realDelegate && [realDelegate isKindOfClass:NSClassFromString(@"UIEditUserWordController")]) {
      return ret;
      }

      if (realDelegate && [realDelegate respondsToSelector:@selector(textFieldShouldReturn:)])
      ret = [realDelegate textFieldShouldReturn:textField];
      BOOL (^block)(UITextField *) = [self blockImplementationForMethod:_cmd];
      if (block)
      ret &= block(textField);
      return ret;
      }

    @EnD

    #pragma mark - Category

    @implementation UITextField (BlocksKit)

    @dynamic bk_shouldBeginEditingBlock, bk_didBeginEditingBlock, bk_shouldEndEditingBlock, bk_didEndEditingBlock, bk_shouldChangeCharactersInRangeWithReplacementStringBlock, bk_shouldClearBlock, bk_shouldReturnBlock;

    • (void)load {
      [self bk_registerDynamicDelegate];
      [self bk_linkDelegateMethods: @{
      @"bk_shouldBeginEditingBlock": @"textFieldShouldBeginEditing:",
      @"bk_didBeginEditingBlock": @"textFieldDidBeginEditing:",
      @"bk_shouldEndEditingBlock": @"textFieldShouldEndEditing:",
      @"bk_didEndEditingBlock" : @"textFieldDidEndEditing:",
      @"bk_shouldChangeCharactersInRangeWithReplacementStringBlock" : @"textField:shouldChangeCharactersInRange:replacementString:",
      @"bk_shouldClearBlock" : @"textFieldShouldClear:",
      @"bk_shouldReturnBlock" : @"textFieldShouldReturn:",
      }];
      }

    @EnD

  2. added a commit that references this issue on Jan 12, 2017
  3. added a commit that references this issue on Apr 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions