Skip to content

Commit afa8238

Browse files
committed
fix: improve scientific notation parsing in spatial datatypes
- Only allow +/- signs after E/e in exponents (more precise validation) - Add comprehensive test coverage for edge cases - Test negative coords, small values, and both Geography/Geometry types
1 parent 69cc640 commit afa8238

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,10 @@ void readPointWkt() throws SQLServerException {
14851485
while (currentWktPos < wkt.length()
14861486
&& (Character.isDigit(wkt.charAt(currentWktPos)) || wkt.charAt(currentWktPos) == '.'
14871487
|| wkt.charAt(currentWktPos) == 'E' || wkt.charAt(currentWktPos) == 'e'
1488-
|| wkt.charAt(currentWktPos) == '-')) {
1488+
|| ((wkt.charAt(currentWktPos) == '-' || wkt.charAt(currentWktPos) == '+')
1489+
&& currentWktPos > startPos
1490+
&& (wkt.charAt(currentWktPos - 1) == 'E'
1491+
|| wkt.charAt(currentWktPos - 1) == 'e')))) {
14891492
currentWktPos++;
14901493
}
14911494

src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,10 +2128,45 @@ public void testLargeCases() throws SQLException {
21282128
*/
21292129
@Test
21302130
public void testGeographySmallCoordinates() throws SQLException {
2131-
Geography g = Geography.point(0.0001234, 1.234, 4326);
2132-
2133-
assertEquals(0.0001234, g.getLatitude());
2134-
assertEquals(1.234, g.getLongitude());
2131+
// Test 1: Positive small latitude (original test case)
2132+
Geography g1 = Geography.point(0.0001234, 1.234, 4326);
2133+
assertEquals(0.0001234, g1.getLatitude(), 1e-10);
2134+
assertEquals(1.234, g1.getLongitude(), 1e-10);
2135+
2136+
// Test 2: Negative small latitude (tests both leading minus and exponent minus)
2137+
Geography g2 = Geography.point(-0.0001234, 1.234, 4326);
2138+
assertEquals(-0.0001234, g2.getLatitude(), 1e-10);
2139+
assertEquals(1.234, g2.getLongitude(), 1e-10);
2140+
2141+
// Test 3: Small longitude
2142+
Geography g3 = Geography.point(45.678, 0.0001234, 4326);
2143+
assertEquals(45.678, g3.getLatitude(), 1e-10);
2144+
assertEquals(0.0001234, g3.getLongitude(), 1e-10);
2145+
2146+
// Test 4: Negative small longitude
2147+
Geography g4 = Geography.point(45.678, -0.0001234, 4326);
2148+
assertEquals(45.678, g4.getLatitude(), 1e-10);
2149+
assertEquals(-0.0001234, g4.getLongitude(), 1e-10);
2150+
2151+
// Test 5: Both coordinates small
2152+
Geography g5 = Geography.point(0.0001234, 0.0005678, 4326);
2153+
assertEquals(0.0001234, g5.getLatitude(), 1e-10);
2154+
assertEquals(0.0005678, g5.getLongitude(), 1e-10);
2155+
2156+
// Test 6: Very small value (more extreme scientific notation)
2157+
Geography g6 = Geography.point(0.00000001234, 90.0, 4326);
2158+
assertEquals(0.00000001234, g6.getLatitude(), 1e-15);
2159+
assertEquals(90.0, g6.getLongitude(), 1e-10);
2160+
2161+
// Test 7: Both negative and small
2162+
Geography g7 = Geography.point(-0.0001234, -0.0005678, 4326);
2163+
assertEquals(-0.0001234, g7.getLatitude(), 1e-10);
2164+
assertEquals(-0.0005678, g7.getLongitude(), 1e-10);
2165+
2166+
// Test 8: Test with Geometry type as well (note: Geometry uses x,y not lat,lon)
2167+
Geometry geom = Geometry.point(1.234, 0.0001234, 0);
2168+
assertEquals(1.234, geom.getX(), 1e-10);
2169+
assertEquals(0.0001234, geom.getY(), 1e-10);
21352170
}
21362171

21372172
private void beforeEachSetup() throws SQLException {

0 commit comments

Comments
 (0)