Skip to content

Commit 6998c93

Browse files
yeesianvisr
authored andcommitted
Add bounds checking when indexing into collections
Fixes #130
1 parent 39921d6 commit 6998c93

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

src/geos_functions.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ end
7676

7777
# Set ordinate values in a Coordinate Sequence (Return 0 on exception)
7878
function setX!(ptr::GEOSCoordSeq, i::Integer, value::Real, context::GEOSContext = _context)
79+
if !(0 < i <= getSize(ptr, context))
80+
error("LibGEOS: i=$i is out of bounds for CoordSeq with size=$(getSize(ptr, context))")
81+
end
7982
result = GEOSCoordSeq_setX_r(context.ptr, ptr, i - 1, value)
8083
if result == 0
8184
error("LibGEOS: Error in GEOSCoordSeq_setX")
@@ -84,6 +87,9 @@ function setX!(ptr::GEOSCoordSeq, i::Integer, value::Real, context::GEOSContext
8487
end
8588

8689
function setY!(ptr::GEOSCoordSeq, i::Integer, value::Real, context::GEOSContext = _context)
90+
if !(0 < i <= getSize(ptr, context))
91+
error("LibGEOS: i=$i is out of bounds for CoordSeq with size=$(getSize(ptr, context))")
92+
end
8793
result = GEOSCoordSeq_setY_r(context.ptr, ptr, i - 1, value)
8894
if result == 0
8995
error("LibGEOS: Error in GEOSCoordSeq_setY")
@@ -92,6 +98,9 @@ function setY!(ptr::GEOSCoordSeq, i::Integer, value::Real, context::GEOSContext
9298
end
9399

94100
function setZ!(ptr::GEOSCoordSeq, i::Integer, value::Real, context::GEOSContext = _context)
101+
if !(0 < i <= getSize(ptr, context))
102+
error("LibGEOS: i=$i is out of bounds for CoordSeq with size=$(getSize(ptr, context))")
103+
end
95104
result = GEOSCoordSeq_setZ_r(context.ptr, ptr, i - 1, value)
96105
if result == 0
97106
error("LibGEOS: Error in GEOSCoordSeq_setZ")
@@ -128,6 +137,9 @@ function setCoordSeq!(
128137
)
129138
ndim = length(coords)
130139
@assert ndim >= 2
140+
if !(0 < i <= getSize(ptr, context))
141+
error("LibGEOS: i=$i is out of bounds for CoordSeq with size=$(getSize(ptr, context))")
142+
end
131143
setX!(ptr, i, coords[1], context)
132144
setY!(ptr, i, coords[2], context)
133145
ndim >= 3 && setZ!(ptr, i, coords[3], context)
@@ -188,6 +200,9 @@ function createCoordSeq(coords::Vector{Vector{Float64}}, context::GEOSContext =
188200
end
189201

190202
function getX(ptr::GEOSCoordSeq, i::Integer, context::GEOSContext = _context)
203+
if !(0 < i <= getSize(ptr, context))
204+
error("LibGEOS: i=$i is out of bounds for CoordSeq with size=$(getSize(ptr, context))")
205+
end
191206
out = Ref{Float64}()
192207
result = GEOSCoordSeq_getX_r(context.ptr, ptr, i - 1, out)
193208
if result == 0
@@ -208,6 +223,9 @@ function getX(ptr::GEOSCoordSeq, context::GEOSContext = _context)
208223
end
209224

210225
function getY(ptr::GEOSCoordSeq, i::Integer, context::GEOSContext = _context)
226+
if !(0 < i <= getSize(ptr, context))
227+
error("LibGEOS: i=$i is out of bounds for CoordSeq with size=$(getSize(ptr, context))")
228+
end
211229
out = Ref{Float64}()
212230
result = GEOSCoordSeq_getY_r(context.ptr, ptr, i - 1, out)
213231
if result == 0
@@ -228,6 +246,9 @@ function getY(ptr::GEOSCoordSeq, context::GEOSContext = _context)
228246
end
229247

230248
function getZ(ptr::GEOSCoordSeq, i::Integer, context::GEOSContext = _context)
249+
if !(0 < i <= getSize(ptr, context))
250+
error("LibGEOS: i=$i is out of bounds for CoordSeq with size=$(getSize(ptr, context))")
251+
end
231252
out = Ref{Float64}()
232253
result = GEOSCoordSeq_getZ_r(context.ptr, ptr, i - 1, out)
233254
if result == 0
@@ -248,6 +269,9 @@ function getZ(ptr::GEOSCoordSeq, context::GEOSContext = _context)
248269
end
249270

250271
function getCoordinates(ptr::GEOSCoordSeq, i::Integer, context::GEOSContext = _context)
272+
if !(0 < i <= getSize(ptr, context))
273+
error("LibGEOS: i=$i is out of bounds for CoordSeq with size=$(getSize(ptr, context))")
274+
end
251275
ndim = getDimensions(ptr, context)
252276
coord = Array{Float64}(undef, ndim)
253277
start = pointer(coord)
@@ -1240,6 +1264,9 @@ end
12401264

12411265
# Call only on LINESTRING, and must be freed by caller (Returns NULL on exception)
12421266
function getPoint(ptr::GEOSGeom, n::Integer, context::GEOSContext = _context)
1267+
if !(0 < n <= numPoints(ptr, context))
1268+
error("LibGEOS: n=$n is out of bounds for LineString with numPoints=$(numPoints(ptr, context))")
1269+
end
12431270
result = GEOSGeomGetPointN_r(context.ptr, ptr, n - 1)
12441271
if result == C_NULL
12451272
error("LibGEOS: Error in GEOSGeomGetPointN")

test/test_geos_functions.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,14 @@ end
4545
b = LibGEOS.cloneCoordSeq(a)
4646
@test LibGEOS.getCoordinates(b) == LibGEOS.getCoordinates(a)
4747
LibGEOS.setCoordSeq!(b, 2, [3.0, 3.0, 3.0])
48+
@test_throws ErrorException LibGEOS.setCoordSeq!(b, 0, [3.0, 3.0, 3.0])
49+
@test_throws ErrorException LibGEOS.setCoordSeq!(b, 5, [3.0, 3.0, 3.0])
4850
@test LibGEOS.getCoordinates(a) ==
4951
Vector{Float64}[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
5052
@test LibGEOS.getCoordinates(b) ==
5153
Vector{Float64}[[1, 2, 3], [3, 3, 3], [7, 8, 9], [10, 11, 12]]
54+
@test_throws ErrorException LibGEOS.getCoordinates(b, 0)
55+
@test_throws ErrorException LibGEOS.getCoordinates(b, 5)
5256
c = LibGEOS.createPoint(LibGEOS.createCoordSeq(Vector{Float64}[[1, 2]]))
5357
@test LibGEOS.getCoordinates(LibGEOS.getCoordSeq(c))[1] [1, 2] atol = 1e-5
5458

@@ -185,9 +189,21 @@ end
185189
LibGEOS.setX!(cs_, 1, x)
186190
LibGEOS.setY!(cs_, 1, y)
187191
LibGEOS.setZ!(cs_, 1, z)
192+
@test_throws ErrorException LibGEOS.setX!(cs_, 0, x)
193+
@test_throws ErrorException LibGEOS.setX!(cs_, 2, x)
194+
@test_throws ErrorException LibGEOS.setY!(cs_, 0, y)
195+
@test_throws ErrorException LibGEOS.setY!(cs_, 2, y)
196+
@test_throws ErrorException LibGEOS.setZ!(cs_, 0, z)
197+
@test_throws ErrorException LibGEOS.setZ!(cs_, 2, z)
188198
@test LibGEOS.getX(cs_, 1) x atol = 1e-5
189199
@test LibGEOS.getY(cs_, 1) y atol = 1e-5
190200
@test LibGEOS.getZ(cs_, 1) z atol = 1e-5
201+
@test_throws MethodError LibGEOS.getX(cs_, 0, x)
202+
@test_throws MethodError LibGEOS.getX(cs_, 2, x)
203+
@test_throws MethodError LibGEOS.getY(cs_, 0, y)
204+
@test_throws MethodError LibGEOS.getY(cs_, 2, y)
205+
@test_throws MethodError LibGEOS.getZ(cs_, 0, z)
206+
@test_throws MethodError LibGEOS.getZ(cs_, 2, z)
191207

192208
cs_ = LibGEOS.createCoordSeq(1, ndim = 3)
193209
@test LibGEOS.getSize(cs_) == 1
@@ -371,6 +387,8 @@ end
371387
@test !LibGEOS.isClosed(geom1)
372388
@test LibGEOS.geomTypeId(geom1) == LibGEOS.GEOS_LINESTRING
373389
@test LibGEOS.numPoints(geom1) == 3
390+
@test_throws ErrorException LibGEOS.getPoint(geom1, 0)
391+
@test_throws ErrorException LibGEOS.getPoint(geom1, 4)
374392
@test LibGEOS.geomLength(geom1) sqrt(100 + 100) atol = 1e-5
375393
geom2 = LibGEOS.getPoint(geom1, 1)
376394
@test LibGEOS.getGeomX(geom2) 0.0 atol = 1e-5

0 commit comments

Comments
 (0)