Skip to content
This repository has been archived by the owner on May 20, 2024. It is now read-only.

Commit

Permalink
Fix XML escaping issue (#2204)
Browse files Browse the repository at this point in the history
* Fix XML escaping issue

* Add note to removing XML escaping if library fixed
  • Loading branch information
nicksellen authored Oct 11, 2020
1 parent 78e48e2 commit cbcd87e
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 21 deletions.
66 changes: 45 additions & 21 deletions src/maps/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,53 @@ 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,
},
// Remove this handling if https://github.com/davidcalhoun/jstoxml/issues/41 gets fixed!
_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 => ({
'<': '&lt;',
'>': '&gt;',
'&': '&amp;',
'"': '&quot;',
"'": '&apos;',
}[c]))
}
34 changes: 34 additions & 0 deletions src/maps/export.spec.js
Original file line number Diff line number Diff line change
@@ -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(`
<?xml version="1.0" encoding="UTF-8"?>
<gpx 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">
<wpt lat="0" lon="0">
<name>foobar</name>
<type>groups</type>
</wpt>
</gpx>
`.trim().replace(/\s*\n\s*/g, ''),
)
})

it('escapes content correctly', () => {
const marker = groupMarker(makeGroup({ name: 'foo & bar' }))
expect(markersAsGPX([marker])).toBe(`
<?xml version="1.0" encoding="UTF-8"?>
<gpx 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">
<wpt lat="0" lon="0">
<name>foo &amp; bar</name>
<type>groups</type>
</wpt>
</gpx>
`.trim().replace(/\s*\n\s*/g, ''),
)
})
})

0 comments on commit cbcd87e

Please sign in to comment.