Commit 560b3724 authored by Evan W. Patton's avatar Evan W. Patton Committed by Susan Rati Lane

Remove BOM from GeoJSON files

While GeoJSON files should not have a BOM per the spec, sometimes
systems will include the UTF byte order marker (BOM). This breaks the
JSON parsing on both in the web client and app. This change will check
for and strip out the BOM before passing the JSON string along for
further processing.

Change-Id: I9452871e19b3985f9beea48b30cf49b60e4835cb
parent 0206b006
...@@ -180,6 +180,7 @@ public class MockFeatureCollection extends MockContainer implements MockMapFeatu ...@@ -180,6 +180,7 @@ public class MockFeatureCollection extends MockContainer implements MockMapFeatu
if (collection) { if (collection) {
var self = this; var self = this;
map.removeLayer(collection); map.removeLayer(collection);
if (geojson.charCodeAt = 0xFEFF) geojson = geojson.substr(1); // strip byte order marker, if present
collection = top.L.geoJson(JSON.parse(geojson), { collection = top.L.geoJson(JSON.parse(geojson), {
pointToLayer: function(feature, latlng) { pointToLayer: function(feature, latlng) {
for (var key in feature.properties) { for (var key in feature.properties) {
......
...@@ -355,7 +355,7 @@ public abstract class MapFeatureContainerBase extends AndroidViewComponent imple ...@@ -355,7 +355,7 @@ public abstract class MapFeatureContainerBase extends AndroidViewComponent imple
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected void processGeoJSON(final String url, final String content) throws JSONException { protected void processGeoJSON(final String url, final String content) throws JSONException {
JSONObject parsedData = new JSONObject(content); JSONObject parsedData = new JSONObject(stripBOM(content));
String type = parsedData.optString(GEOJSON_TYPE); String type = parsedData.optString(GEOJSON_TYPE);
if (!GEOJSON_FEATURECOLLECTION.equals(type) && !GEOJSON_GEOMETRYCOLLECTION.equals(type)) { if (!GEOJSON_FEATURECOLLECTION.equals(type) && !GEOJSON_GEOMETRYCOLLECTION.equals(type)) {
$form().runOnUiThread(new Runnable() { $form().runOnUiThread(new Runnable() {
...@@ -425,4 +425,12 @@ public abstract class MapFeatureContainerBase extends AndroidViewComponent imple ...@@ -425,4 +425,12 @@ public abstract class MapFeatureContainerBase extends AndroidViewComponent imple
return YailList.makeList(items); return YailList.makeList(items);
} }
private static String stripBOM(String content) {
if (content.charAt(0) == '\uFEFF') {
return content.substring(1);
} else {
return content;
}
}
} }
...@@ -201,6 +201,18 @@ public class FeatureCollectionTest extends MapTestBase { ...@@ -201,6 +201,18 @@ public class FeatureCollectionTest extends MapTestBase {
assertEquals(getMap(), collection.getMap()); assertEquals(getMap(), collection.getMap());
} }
/**
* Tests that the FeatureCollection can load a GeoJSON file with an invalid BOM. Technically, BOM is not allowed
* by the JSON RFC, but who needs standards anyway?
*/
@Test
public void testGeoJSONWithBOM() {
ShadowEventDispatcher.clearEvents();
collection.FeaturesFromGeoJSON("\uFEFF{\"type\":\"FeatureCollection\",\"features\":[]}");
runAllEvents();
assertEventFiredAny(collection, "GotFeatures");
}
private void testFeatureListSetter(MapFeature feature) { private void testFeatureListSetter(MapFeature feature) {
ShadowView view = Shadow.extract(getMap().getView()); ShadowView view = Shadow.extract(getMap().getView());
view.clearWasInvalidated(); view.clearWasInvalidated();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment