Skip to content

Commit 11e2bf4

Browse files
committed
handle buffer reading
for invalid buffer input by user
1 parent 9e697a5 commit 11e2bf4

3 files changed

Lines changed: 80 additions & 38 deletions

File tree

src/main/java/com/microsoft/sqlserver/jdbc/Geography.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import java.nio.ByteBuffer;
99
import java.nio.ByteOrder;
10+
import java.text.MessageFormat;
1011

1112

1213
public class Geography extends SQLServerSpatialDatatype {
@@ -368,10 +369,10 @@ protected void serializeToWkb(boolean noZM) {
368369
return;
369370
}
370371

371-
protected void parseWkb() {
372-
srid = buffer.getInt();
373-
version = buffer.get();
374-
serializationProperties = buffer.get();
372+
protected void parseWkb() throws SQLServerException {
373+
srid = readInt();
374+
version = readByte();
375+
serializationProperties = readByte();
375376

376377
interpretSerializationPropBytes();
377378
readNumberOfPoints();
@@ -402,11 +403,17 @@ protected void parseWkb() {
402403
}
403404
}
404405

405-
private void readPoints() {
406-
points = new double[2 * numberOfPoints];
406+
private void readPoints() throws SQLServerException {
407+
try {//if no limit of points is allowed, this should be an array of arrays
408+
points = new double[2 * numberOfPoints];
409+
} catch (NegativeArraySizeException | OutOfMemoryError e) {
410+
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_ParsingError"));
411+
Object[] msgArgs = {JDBCType.VARBINARY};//should throw some kind of 'array size too large error here'
412+
throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
413+
}
407414
for (int i = 0; i < numberOfPoints; i++) {
408-
points[2 * i + 1] = buffer.getDouble();
409-
points[2 * i] = buffer.getDouble();
415+
points[2 * i + 1] = readDouble();
416+
points[2 * i] = readDouble();
410417
}
411418
}
412419
}

src/main/java/com/microsoft/sqlserver/jdbc/Geometry.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,10 @@ protected void serializeToWkb(boolean noZM) {
369369
return;
370370
}
371371

372-
protected void parseWkb() {
373-
srid = buffer.getInt();
374-
version = buffer.get();
375-
serializationProperties = buffer.get();
372+
protected void parseWkb() throws SQLServerException {
373+
srid = readInt();
374+
version = readByte();
375+
serializationProperties = readByte();
376376

377377
interpretSerializationPropBytes();
378378
readNumberOfPoints();
@@ -403,11 +403,11 @@ protected void parseWkb() {
403403
}
404404
}
405405

406-
private void readPoints() {
406+
private void readPoints() throws SQLServerException {
407407
points = new double[2 * numberOfPoints];
408408
for (int i = 0; i < numberOfPoints; i++) {
409-
points[2 * i] = buffer.getDouble();
410-
points[2 * i + 1] = buffer.getDouble();
409+
points[2 * i] = readDouble();
410+
points[2 * i + 1] = readDouble();
411411
}
412412
}
413413
}

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package com.microsoft.sqlserver.jdbc;
77

88
import java.math.BigDecimal;
9+
import java.nio.BufferUnderflowException;
910
import java.nio.ByteBuffer;
1011
import java.text.MessageFormat;
1112
import java.util.ArrayList;
@@ -98,7 +99,7 @@ abstract class SQLServerSpatialDatatype {
9899
* corresponding data structures.
99100
*
100101
*/
101-
protected abstract void parseWkb();
102+
protected abstract void parseWkb() throws SQLServerException;
102103

103104
/**
104105
* Create the WKT representation of Geometry/Geography from the deserialized data.
@@ -1234,71 +1235,82 @@ protected void interpretSerializationPropBytes() {
12341235
isLargerThanHemisphere = (serializationProperties & isLargerThanHemisphereMask) != 0;
12351236
}
12361237

1237-
protected void readNumberOfPoints() {
1238+
protected void readNumberOfPoints() throws SQLServerException {
12381239
if (isSinglePoint) {
12391240
numberOfPoints = 1;
12401241
} else if (isSingleLineSegment) {
12411242
numberOfPoints = 2;
12421243
} else {
1243-
numberOfPoints = buffer.getInt();
1244+
numberOfPoints = readInt();
1245+
if (numberOfPoints <= 0) {
1246+
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_ParsingError"));
1247+
Object[] msgArgs = {JDBCType.VARBINARY};
1248+
throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
1249+
}
12441250
}
12451251
}
12461252

1247-
protected void readZvalues() {
1253+
protected void readZvalues() throws SQLServerException {
12481254
zValues = new double[numberOfPoints];
12491255
for (int i = 0; i < numberOfPoints; i++) {
1250-
zValues[i] = buffer.getDouble();
1256+
zValues[i] = readDouble();
12511257
}
12521258
}
12531259

1254-
protected void readMvalues() {
1260+
protected void readMvalues() throws SQLServerException {
12551261
mValues = new double[numberOfPoints];
12561262
for (int i = 0; i < numberOfPoints; i++) {
1257-
mValues[i] = buffer.getDouble();
1263+
mValues[i] = readDouble();
12581264
}
12591265
}
12601266

1261-
protected void readNumberOfFigures() {
1262-
numberOfFigures = buffer.getInt();
1267+
protected void readNumberOfFigures() throws SQLServerException {
1268+
numberOfFigures = readInt();
12631269
}
12641270

1265-
protected void readFigures() {
1271+
protected void readFigures() throws SQLServerException {
12661272
byte fa;
12671273
int po;
12681274
figures = new Figure[numberOfFigures];
12691275
for (int i = 0; i < numberOfFigures; i++) {
1270-
fa = buffer.get();
1271-
po = buffer.getInt();
1276+
fa = readByte();
1277+
po = readInt();
12721278
figures[i] = new Figure(fa, po);
12731279
}
12741280
}
12751281

1276-
protected void readNumberOfShapes() {
1277-
numberOfShapes = buffer.getInt();
1282+
protected void readNumberOfShapes() throws SQLServerException {
1283+
numberOfShapes = readInt();
12781284
}
12791285

1280-
protected void readShapes() {
1286+
protected void readShapes() throws SQLServerException {
12811287
int po;
12821288
int fo;
12831289
byte ogt;
12841290
shapes = new Shape[numberOfShapes];
12851291
for (int i = 0; i < numberOfShapes; i++) {
1286-
po = buffer.getInt();
1287-
fo = buffer.getInt();
1288-
ogt = buffer.get();
1292+
po = readInt();
1293+
fo = readInt();
1294+
ogt = readByte();
12891295
shapes[i] = new Shape(po, fo, ogt);
12901296
}
12911297
}
12921298

1293-
protected void readNumberOfSegments() {
1294-
numberOfSegments = buffer.getInt();
1299+
protected void readNumberOfSegments() throws SQLServerException {
1300+
numberOfSegments = readInt();
12951301
}
12961302

1297-
protected void readSegments() {
1303+
protected void readSegments() throws SQLServerException {
12981304
byte st;
1299-
segments = new Segment[numberOfSegments];
1305+
try {
1306+
segments = new Segment[numberOfSegments];
1307+
} catch (NegativeArraySizeException | OutOfMemoryError e) {
1308+
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_ParsingError"));
1309+
Object[] msgArgs = {JDBCType.VARBINARY};//should throw some kind of 'array size too large error here'
1310+
throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
1311+
}
13001312
for (int i = 0; i < numberOfSegments; i++) {
1301-
st = buffer.get();
1313+
st = readByte();
13021314
segments[i] = new Segment(st);
13031315
}
13041316
}
@@ -1646,6 +1658,29 @@ private void skipWhiteSpaces() {
16461658
currentWktPos++;
16471659
}
16481660
}
1661+
1662+
private void checkBuffer(int i) throws SQLServerException {
1663+
if (buffer.remaining() < i) {
1664+
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_ParsingError"));
1665+
Object[] msgArgs = {JDBCType.VARBINARY};//invalid buffer error message maybe?
1666+
throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
1667+
}
1668+
}
1669+
1670+
protected byte readByte() throws SQLServerException {
1671+
checkBuffer(1);
1672+
return buffer.get();
1673+
}
1674+
1675+
protected int readInt() throws SQLServerException {
1676+
checkBuffer(4);
1677+
return buffer.getInt();
1678+
}
1679+
1680+
protected double readDouble() throws SQLServerException {
1681+
checkBuffer(8);
1682+
return buffer.getDouble();
1683+
}
16491684
}
16501685

16511686

0 commit comments

Comments
 (0)