From 8b08d8ae2456a69e48b1c781843cb6f77259d982 Mon Sep 17 00:00:00 2001 From: Nick Sellen Date: Sat, 10 Oct 2020 15:12:48 +0200 Subject: [PATCH 1/2] Fix XML escaping issue --- src/maps/export.js | 65 ++++++++++++++++++++++++++++------------- src/maps/export.spec.js | 34 +++++++++++++++++++++ 2 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 src/maps/export.spec.js diff --git a/src/maps/export.js b/src/maps/export.js index 5ac535183..97dc0d5e5 100644 --- a/src/maps/export.js +++ b/src/maps/export.js @@ -3,29 +3,52 @@ import { saveAs } from 'file-saver' export function exportAsGPX (markers, filename) { saveAs(new Blob( - [toXML({ - _name: 'gpx', - _attrs: { - version: '1.1', - 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation': 'http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd', - }, - _content: markers.map(marker => { - const { lat, lng: lon } = marker.latLng - return { - _name: 'wpt', - _attrs: { - lat, - lon, - }, - _content: marker.gpx, - } - }), - }, { - header: true, - })], + [markersAsGPX(markers)], { type: 'application/gpx+xml', }, ), filename) } + +export function markersAsGPX (markers) { + return toXML({ + _name: 'gpx', + _attrs: { + version: '1.1', + 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation': 'http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd', + }, + _content: markers.map(marker => { + const { lat, lng: lon } = marker.latLng + return { + _name: 'wpt', + _attrs: { + lat, + lon, + }, + _content: escapeObject(marker.gpx), + } + }), + }, { + header: true, + }) +} + +// Only escapes top level values and assumes they are strings +function escapeObject (obj) { + const newObj = {} + for (const key of Object.keys(obj)) { + newObj[key] = escapeValue(obj[key]) + } + return newObj +} + +function escapeValue (content) { + return content.replace(/[<>&"']/g, c => ({ + '<': '<', + '>': '>', + '&': '&', + '"': '"', + "'": ''', + }[c])) +} diff --git a/src/maps/export.spec.js b/src/maps/export.spec.js new file mode 100644 index 000000000..419442271 --- /dev/null +++ b/src/maps/export.spec.js @@ -0,0 +1,34 @@ +import { groupMarker } from './components/markers' +import { makeGroup } from '>/enrichedFactories' + +import { markersAsGPX } from './export' + +describe('map export', () => { + it('creates GPX', async () => { + const marker = groupMarker(makeGroup({ name: 'foobar' })) + expect(markersAsGPX([marker])).toBe(` + + + + foobar + groups + + + `.trim().replace(/\s*\n\s*/g, ''), + ) + }) + + it('escapes content correctly', () => { + const marker = groupMarker(makeGroup({ name: 'foo & bar' })) + expect(markersAsGPX([marker])).toBe(` + + + + foo & bar + groups + + + `.trim().replace(/\s*\n\s*/g, ''), + ) + }) +}) From 8df4c811963865f3fdc9ed8c24fdcf4b0d388ef8 Mon Sep 17 00:00:00 2001 From: Nick Sellen Date: Sat, 10 Oct 2020 15:28:20 +0200 Subject: [PATCH 2/2] Add note to removing XML escaping if library fixed --- src/maps/export.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/maps/export.js b/src/maps/export.js index 97dc0d5e5..aa7746712 100644 --- a/src/maps/export.js +++ b/src/maps/export.js @@ -26,6 +26,7 @@ export function markersAsGPX (markers) { lat, lon, }, + // Remove this handling if https://github.com/davidcalhoun/jstoxml/issues/41 gets fixed! _content: escapeObject(marker.gpx), } }),