Question for my Swift friends:
I'm seeing "lowerBound <= upperBound" crashes in a function similar to this.

If the range is constrained by another range (the line), how is it possible for it to go out of bounds?

What am I missing? Seems fine on all inputs I can think of.

@phill I work with ranges a lot. And I've been starring at this for a while now and I don't *yet* see any issue.

@mattiem it's weird right!? Only thing that has a wiff of suspicion is it takes a ‘locale’ argument which could be doing...something.

@phill Could it be that lineRange(for:) and range(of: range:) are assuming UTF-16 (all NSString apis do this), but the rest aren't? It does kinda look like you may be mixing this with String APIs here. Try emojis in your tests!

@mattiem oooo that’s a good suggestion! I’ll give it a go when I’m back at my desk.

Spec says servers shouldn’t be returning those unencoded…but since when has that stopped them 🤓

@phill Doubling what @mattiem said, make sure you never mix String and NSString indexes and ranges. The toll-free bringing means String has a lot of useful methods, but that are not all inter-compatible in subtle ways…

@phill as for test inputs, perhaps one of these might trigger it? (Not at a computer, so I can’t try myself…)
```
Header: value:value
: No Header
```

@phill Finally, I would look at line range misbehaving and giving you something you are not expecting, perhaps when \r is used on its own, or maybe some abomination like \r\r

@dimitribouniol Thanks Dimitri these are really great suggestions!

I don't *think* I'm mixing indexes and ranges. It looks like range(of:range:) and lineRange both return String.Index.

The test input of a blank key and multiple colons looks alright too. And \r\r just gets treated as two lines, and so the second line just returns nil on the match.

Vexing!

@phill Keep in mind NSRange toll free bridges to Range<String.Index>, which is what I meant. Double to check to see if the method you are using comes from NSString (which you can only do via documentation I think?) — if it does, only use the range with NSString methods.

Follow

@dimitribouniol Ahh-ha, yes it does look like lineRange is from NSString, as is range(of:). Perhaps there is some utf8 to utf16 weirdness going on then.

@phill Yeah, likely complicated by different implementations on linux than on macOS 😅

I’d love to say try to use the pure Swift strings, but they lack a lot of functionality unfortunately 😔 I usually end up digging in the stdlib repo on github to see what has a reasonable implementation and what bridges…

@dimitribouniol Yeah I've decided it's probably simpler to just do away with those methods entirely.

It's not as elegant, but hey, it's a lot more predictable.

Thanks for your help!

@phill Probably a bit faster once optimizations kick in too 🤣

Sign in to participate in the conversation
The Not So Big Company

The home of The Not So Big Company on Mastodon.