Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit 77d0db5

Browse files
committed
Added index checks in UTF16String
1 parent 087e2a3 commit 77d0db5

File tree

2 files changed

+101
-11
lines changed

2 files changed

+101
-11
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* This file is part of AndroidIDE.
3+
*
4+
* AndroidIDE is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* AndroidIDE is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.itsaky.androidide.treesitter.string;
19+
20+
/**
21+
* Assertions used in {@link UTF16String}.
22+
*
23+
* @author Akash Yadav
24+
*/
25+
class Assertions {
26+
27+
private Assertions() {
28+
throw new UnsupportedOperationException();
29+
}
30+
31+
public static void checkIndex(int index, int size) {
32+
if (index < 0 || index >= size) {
33+
throw new IndexOutOfBoundsException("index " + index + " out of bounds, size = " + size);
34+
}
35+
}
36+
37+
public static void checkStringRange(String str, int off, int len) {
38+
if (off < 0 || off + len > str.length()) {
39+
throw new StringIndexOutOfBoundsException("offset: " + off + ", len: " + len + ", actual length: " + str.length());
40+
}
41+
}
42+
}

android-tree-sitter/src/main/java/com/itsaky/androidide/treesitter/string/UTF16String.java

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
package com.itsaky.androidide.treesitter.string;
1919

20+
import static com.itsaky.androidide.treesitter.string.Assertions.checkIndex;
21+
import static com.itsaky.androidide.treesitter.string.Assertions.checkStringRange;
22+
2023
import java.util.Objects;
2124

2225
/**
@@ -36,6 +39,7 @@ public class UTF16String implements CharSequence, AutoCloseable {
3639
* @return The byte.
3740
*/
3841
public byte byteAt(int index) {
42+
checkIndex(index, byteLength());
3943
return Native.byteAt(this.pointer, index);
4044
}
4145

@@ -45,6 +49,7 @@ public byte byteAt(int index) {
4549
* @param index The index of the byte.
4650
*/
4751
public void setByteAt(int index, byte b) {
52+
checkIndex(index, byteLength());
4853
Native.setByteAt(this.pointer, index, b);
4954
}
5055

@@ -56,6 +61,7 @@ public void setByteAt(int index, byte b) {
5661
*/
5762
@Override
5863
public char charAt(int index) {
64+
checkIndex(index, length());
5965
return Native.chatAt(this.pointer, index);
6066
}
6167

@@ -65,6 +71,7 @@ public char charAt(int index) {
6571
* @param index The index of the char.
6672
*/
6773
public void setCharAt(int index, char c) {
74+
checkIndex(index, length());
6875
Native.setCharAt(this.pointer, index, c);
6976
}
7077

@@ -83,9 +90,10 @@ public void append(String string) {
8390
* @param string The string to append.
8491
* @param fromIndex The start offset to append from. This should be Java {@code char}-based index
8592
* in the given string.
86-
* @param length The number of character to append.
93+
* @param length The number of character to append from the given string.
8794
*/
8895
public void append(String string, int fromIndex, int length) {
96+
checkStringRange(string, fromIndex, length);
8997
Native.appendPart(this.pointer, string, fromIndex, length);
9098
}
9199

@@ -97,6 +105,7 @@ public void append(String string, int fromIndex, int length) {
97105
* @param string The string to insert.
98106
*/
99107
public void insert(int index, String string) {
108+
checkIndex(index, length());
100109
Native.insert(this.pointer, string, index);
101110
}
102111

@@ -108,6 +117,9 @@ public void insert(int index, String string) {
108117
* @param toIndex The index to delete to.
109118
*/
110119
public void delete(int fromIndex, int toIndex) {
120+
int size = length();
121+
checkIndex(fromIndex, size);
122+
checkIndex(toIndex, size + 1);
111123
Native.deleteChars(this.pointer, fromIndex, toIndex);
112124
}
113125

@@ -118,6 +130,9 @@ public void delete(int fromIndex, int toIndex) {
118130
* @param toIndex The byte index to delete to.
119131
*/
120132
public void deleteBytes(int fromIndex, int toIndex) {
133+
int size = byteLength();
134+
checkIndex(fromIndex, size);
135+
checkIndex(toIndex, size + 1);
121136
Native.deleteBytes(this.pointer, fromIndex, toIndex);
122137
}
123138

@@ -130,6 +145,14 @@ public void deleteBytes(int fromIndex, int toIndex) {
130145
* @param str The string to replace with.
131146
*/
132147
public void replaceChars(int fromIndex, int toIndex, String str) {
148+
if (str.length() == 0) {
149+
delete(fromIndex, toIndex);
150+
return;
151+
}
152+
153+
int size = length();
154+
checkIndex(fromIndex, size);
155+
checkIndex(toIndex, size + 1);
133156
Native.replaceChars(this.pointer, fromIndex, toIndex, str);
134157
}
135158

@@ -142,6 +165,14 @@ public void replaceChars(int fromIndex, int toIndex, String str) {
142165
* @param str The string to replace with.
143166
*/
144167
public void replaceBytes(int fromIndex, int toIndex, String str) {
168+
if (str.length() == 0) {
169+
deleteBytes(fromIndex, toIndex);
170+
return;
171+
}
172+
173+
int size = byteLength();
174+
checkIndex(fromIndex, size);
175+
checkIndex(toIndex, size + 1);
145176
Native.replaceBytes(this.pointer, fromIndex, toIndex, str);
146177
}
147178

@@ -152,6 +183,7 @@ public void replaceBytes(int fromIndex, int toIndex, String str) {
152183
* @return The subsequence.
153184
*/
154185
public UTF16String subseqChars(int start) {
186+
checkIndex(start, length());
155187
return subseqChars(start, length());
156188
}
157189

@@ -163,6 +195,9 @@ public UTF16String subseqChars(int start) {
163195
* @return The subsequence.
164196
*/
165197
public UTF16String subseqChars(int start, int end) {
198+
int size = length();
199+
checkIndex(start, size);
200+
checkIndex(end, size + 1);
166201
return new UTF16String(Native.substring_chars(this.pointer, start, end));
167202
}
168203

@@ -173,6 +208,8 @@ public UTF16String subseqChars(int start, int end) {
173208
* @return The subsequence.
174209
*/
175210
public UTF16String subseqBytes(int start) {
211+
int size = byteLength();
212+
checkIndex(start, size);
176213
return subseqBytes(start, byteLength());
177214
}
178215

@@ -184,6 +221,9 @@ public UTF16String subseqBytes(int start) {
184221
* @return The subsequence.
185222
*/
186223
public UTF16String subseqBytes(int start, int end) {
224+
int size = byteLength();
225+
checkIndex(start, size);
226+
checkIndex(end, size + 1);
187227
return new UTF16String(Native.substring_bytes(this.pointer, start, end));
188228
}
189229

@@ -194,6 +234,8 @@ public UTF16String subseqBytes(int start, int end) {
194234
* @return The substring.
195235
*/
196236
public String substringChars(int start) {
237+
int size = length();
238+
checkIndex(start, size);
197239
return substringChars(start, length());
198240
}
199241

@@ -205,6 +247,9 @@ public String substringChars(int start) {
205247
* @return The substring.
206248
*/
207249
public String substringChars(int start, int end) {
250+
int size = length();
251+
checkIndex(start, size);
252+
checkIndex(end, size + 1);
208253
return Native.subjstring_chars(this.pointer, start, end);
209254
}
210255

@@ -215,6 +260,8 @@ public String substringChars(int start, int end) {
215260
* @return The substring.
216261
*/
217262
public String substringBytes(int start) {
263+
int size = byteLength();
264+
checkIndex(start, size);
218265
return substringBytes(start, length());
219266
}
220267

@@ -226,6 +273,9 @@ public String substringBytes(int start) {
226273
* @return The substring.
227274
*/
228275
public String substringBytes(int start, int end) {
276+
int size = byteLength();
277+
checkIndex(start, size);
278+
checkIndex(end, size + 1);
229279
return Native.subjstring_bytes(this.pointer, start, end);
230280
}
231281

@@ -238,16 +288,6 @@ public int length() {
238288
return Native.length(this.pointer);
239289
}
240290

241-
@Override
242-
public CharSequence subSequence(int start, int end) {
243-
final var count = length();
244-
if (end < start || start < 0 || end >= count) {
245-
throw new IndexOutOfBoundsException(
246-
"start: " + start + ", end: " + end + ", actual length: " + count);
247-
}
248-
return subseqChars(start, end);
249-
}
250-
251291
/**
252292
* Get the length of this string in terms of Java bytes.
253293
*
@@ -257,6 +297,14 @@ public int byteLength() {
257297
return Native.byteLength(this.pointer);
258298
}
259299

300+
@Override
301+
public CharSequence subSequence(int start, int end) {
302+
final var count = length();
303+
checkIndex(start, count);
304+
checkIndex(start, count + 1);
305+
return subseqChars(start, end);
306+
}
307+
260308
/** Close this string and release resources. */
261309
@Override
262310
public void close() {

0 commit comments

Comments
 (0)