5
5
"bytes"
6
6
_ "embed"
7
7
"encoding/json"
8
+ "errors"
8
9
"flag"
9
10
"fmt"
10
11
"github.com/getsentry/sentry-go"
@@ -251,36 +252,73 @@ func GetPixel(image image.Image, z int, x int, y int) float64 {
251
252
}
252
253
}
253
254
255
+ func parseInput (body io.Reader ) (orb.Geometry , string , string , json.RawMessage , error ) {
256
+ decoder := json .NewDecoder (body )
257
+
258
+ var input Input
259
+ err := decoder .Decode (& input )
260
+ if err != nil {
261
+ return nil , "" , "" , nil , errors .New ("input GeoJSON is invalid" )
262
+ }
263
+
264
+ var geom orb.Geometry
265
+ var sanitizedData json.RawMessage
266
+
267
+ if input .RegionType == "geojson" {
268
+ geojsonGeom , err := geojson .UnmarshalGeometry (input .RegionData )
269
+ if err != nil {
270
+ return nil , "" , "" , nil , errors .New ("input GeoJSON is invalid" )
271
+ }
272
+ geom = geojsonGeom .Geometry ()
273
+ switch v := geom .(type ) {
274
+ case orb.Polygon :
275
+ if len (v ) == 0 {
276
+ return nil , "" , "" , nil , errors .New ("geom does not have enough rings" )
277
+ }
278
+ for _ , ring := range v {
279
+ if len (ring ) < 4 {
280
+ return nil , "" , "" , nil , errors .New ("ring does not have enough coordinates" )
281
+ }
282
+ }
283
+ case orb.MultiPolygon :
284
+ if len (v ) == 0 {
285
+ return nil , "" , "" , nil , errors .New ("geom does not have enough rings" )
286
+ }
287
+ for _ , polygon := range v {
288
+ if len (polygon ) == 0 {
289
+ return nil , "" , "" , nil , errors .New ("geom does not have enough rings" )
290
+ }
291
+ for _ , ring := range polygon {
292
+ if len (ring ) < 4 {
293
+ return nil , "" , "" , nil , errors .New ("ring does not have enough coordinates" )
294
+ }
295
+ }
296
+ }
297
+ }
298
+ sanitizedData , _ = geojsonGeom .MarshalJSON ()
299
+ } else if input .RegionType == "bbox" {
300
+ var coords []float64
301
+ json .Unmarshal (input .RegionData , & coords )
302
+ if len (coords ) < 4 {
303
+ return nil , "" , "" , nil , errors .New ("input does not have >3 coordinates" )
304
+ }
305
+ geom = orb.MultiPoint {orb.Point {coords [1 ], coords [0 ]}, orb.Point {coords [3 ], coords [2 ]}}.Bound ()
306
+ sanitizedData , _ = json .Marshal (coords [0 :4 ])
307
+ } else {
308
+ return nil , "" , "" , nil , errors .New ("invalid input RegionType" )
309
+ }
310
+
311
+ return geom , input .Name , input .RegionType , sanitizedData , nil
312
+ }
313
+
254
314
// check the filesystem for the result JSON
255
315
// if it's not started yet, return the position in the queue
256
316
func (h * server ) ServeHTTP (w http.ResponseWriter , r * http.Request ) {
257
317
w .Header ().Set ("Access-Control-Allow-Origin" , "*" )
258
318
if r .Method == "POST" {
259
- decoder := json . NewDecoder (r .Body )
319
+ geom , sanitized_name , sanitized_type , sanitized_region , err := parseInput (r .Body )
260
320
261
- var input Input
262
- err := decoder .Decode (& input )
263
321
if err != nil {
264
- panic (err )
265
- }
266
-
267
- var geom orb.Geometry
268
- var sanitizedData json.RawMessage
269
- // validate input
270
- if input .RegionType == "geojson" {
271
- geojsonGeom , _ := geojson .UnmarshalGeometry (input .RegionData )
272
- geom = geojsonGeom .Geometry ()
273
- sanitizedData , _ = geojsonGeom .MarshalJSON ()
274
- } else if input .RegionType == "bbox" {
275
- var coords []float64
276
- json .Unmarshal (input .RegionData , & coords )
277
- if len (coords ) < 4 {
278
- w .WriteHeader (400 )
279
- return
280
- }
281
- geom = orb.MultiPoint {orb.Point {coords [1 ], coords [0 ]}, orb.Point {coords [3 ], coords [2 ]}}.Bound ()
282
- sanitizedData , _ = json .Marshal (coords [0 :4 ])
283
- } else {
284
322
w .WriteHeader (400 )
285
323
return
286
324
}
@@ -291,10 +329,7 @@ func (h *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
291
329
return
292
330
}
293
331
294
- // todo: sanitize name
295
- // end validate input
296
-
297
- task := Task {Uuid : uuid .New ().String (), SanitizedName : input .Name , SanitizedRegionType : input .RegionType , SanitizedRegionData : sanitizedData }
332
+ task := Task {Uuid : uuid .New ().String (), SanitizedName : sanitized_name , SanitizedRegionType : sanitized_type , SanitizedRegionData : sanitized_region }
298
333
299
334
select {
300
335
case h .queue <- task :
0 commit comments