这是indexloc提供的服务,不要输入任何密码
Skip to content

FNextPushId 'successor' crash #8790

@mortenbekditlevsen

Description

@mortenbekditlevsen

Step 0: Are you in the right place?

  • For issues or feature requests related to the code in this repository
    file a Github issue.
    • If this is a feature request please use the Feature Request template.
  • For general technical questions, post a question on StackOverflow
    with the firebase tag.
  • For general (non-iOS) Firebase discussion, use the firebase-talk
    google group.
  • For backend issues, console issues, and other non-SDK help that does not fall under one
    of the above categories, reach out to
    Firebase Support.
  • Once you've read this section and determined that your issue is appropriate for
    this repository, please delete this section.

[REQUIRED] Step 1: Describe your environment

  • Xcode version: 13
  • Firebase SDK version: master
  • Installation method: Swift Package Manager
  • Firebase Component: Database

[REQUIRED] Step 2: Describe the problem

The methods successor and predecessor erronously deal with PUSH_CHARS even though it's entirely valid to use unicode keys that are not within the PUSH_CHARS set.

Around line 98 in FNextPushId.m we have:

    NSInteger sourceIndex = [PUSH_CHARS rangeOfString:source].location;
    NSString *sourcePlusOne = [NSString
        stringWithFormat:@"%C", [PUSH_CHARS characterAtIndex:sourceIndex + 1]];

The issue is that if source is for instance a space, then sourceIndex will be max int and the sourcePlusOne calculation causes a crash (since max int + 1 gives min int in objective-c, and min int is out of bounds).

Thread 1: "-[__NSCFConstantString characterAtIndex:]: Range or index out of bounds"

Steps to reproduce:

Easily reproducible with the one-liner below:

Relevant Code:

        let ref = Database.database().reference().queryOrderedByKey().queryStarting(afterValue: " ".padding(toLength: 786, withPad: "z", startingAt: 0))

Suggestion for a solution

I guess that 'successor' and 'predecessor' ought to deal with unicode character points instead of the PUSH_CHARs used to auto-generate keys.
In the same line, I believe that appending MIN_PUSH_CHAR to keys that are shorter than MAX_KEY_LENGTH is not entirely correct, since it wont give the string value that immediately succeeds the input key when using the key index comparison - - which for non-numeric keys ends up using the following comparison:

            return [a compare:b options:NSLiteralSearch];

So 'successor' should return the key that immediately follows the input as defined by the +compareKey:toKey method in FUtilities.

The crash itself is a bit contrived, but here is an actual issue:
If you have the following data in RTDB:
{ "a": "hello",
"a!": "world"
}
and do a queryStarting(afterValue: "a"), then I suspect that the query will start at "a-" meaning that it will miss the "a!" entry...

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions