Skip to content

Commit

Permalink
AsciiBuffer.indexOf returns incorrect result for 2-bytes characters (
Browse files Browse the repository at this point in the history
…#2352)

* `AsciiBuffer.indexOf` returns incorrect result for 2-bytes characters

Motivation:

`AsciiBuffer.indexOf` casts `char` to `byte` by dropping the higher 8
bits. As the result, it may return an index of an ascii character that
has the same lower 8 bits.

Modifications:

- Check character length and return `-1` if it's 2-bytes character;

Result:

Correct result when users try to find an index of a 2-bytes character in
`AsciiBuffer`. Consistency with other `CharSequence` implementations,
like `String` and `StringBuilder`.
  • Loading branch information
idelpivnitskiy committed Sep 12, 2022
1 parent 5e5b746 commit f11310c
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ Buffer unwrap() {
* @throws NullPointerException if {@code subString} is {@code null}.
*/
int indexOf(char ch, int start) {
return buffer.indexOf(start, buffer.writerIndex(), (byte) ch);
return singleByte(ch) ? buffer.indexOf(start, buffer.writerIndex(), (byte) ch) : -1;
}

private static boolean singleByte(char ch) {
return ch >>> 8 == 0;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import java.util.function.Function;

import static io.servicetalk.buffer.api.CharSequences.indexOf;
import static io.servicetalk.buffer.api.CharSequences.newAsciiString;
import static io.servicetalk.buffer.api.CharSequences.split;
import static io.servicetalk.buffer.api.ReadOnlyBufferAllocators.DEFAULT_RO_ALLOCATOR;
Expand Down Expand Up @@ -205,4 +206,27 @@ void parseLongFromSlice() {
assertThat("Unexpected result for AsciiBuffer representation",
CharSequences.parseLong(newAsciiString(buffer.slice(4, 2))), is(42L));
}

@Test
void indexOfAsciiString() {
testIndexOf(newAsciiString("text42text"));
}

@Test
void indexOfString() {
testIndexOf("text42text");
}

@Test
void indexOfStringBuilder() {
testIndexOf(new StringBuilder().append("text42text"));
}

private static void testIndexOf(CharSequence cs) {
assertThat(indexOf(cs, '5', 0), is(-1));
assertThat(indexOf(cs, '2', cs.length() - 3), is(-1));
assertThat(indexOf(cs, '2', 0), is(5));
char twoBytesChar = ('2' << 8) | '2';
assertThat(indexOf(cs, twoBytesChar, 0), is(-1));
}
}

0 comments on commit f11310c

Please sign in to comment.