From 9348350ba3ba1c23aa6273f1eeafe0346a306ba6 Mon Sep 17 00:00:00 2001 From: Boon Boonsiri <35120291+boonboonsiri@users.noreply.github.com> Date: Thu, 12 Oct 2023 01:22:51 -0400 Subject: [PATCH 1/4] Allow base 64 url as images for static maps (#1007) * allow base-64 url as images * Add option to config * Refactoring * Update docs * feat: added base64 url images lint Signed-off-by: Boon Boonsiri --------- Signed-off-by: Boon Boonsiri --- docs/config.rst | 7 +++++++ src/serve_rendered.js | 9 +++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/config.rst b/docs/config.rst index 648957f..e61bb1c 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -157,6 +157,13 @@ Allows the rendering of marker icons fetched via http(s) hyperlinks. For security reasons only allow this if you can control the origins from where the markers are fetched! Default is to disallow fetching of icons from remote sources. +``allowInlineMarkerImages`` +-------------- +Allows the rendering of inline marker icons or base64 urls. +For security reasons only allow this if you can control the origins from where the markers are fetched! +Not used by default. + + ``styles`` ========== diff --git a/src/serve_rendered.js b/src/serve_rendered.js index dd57016..78648d5 100644 --- a/src/serve_rendered.js +++ b/src/serve_rendered.js @@ -279,7 +279,10 @@ const extractMarkersFromQuery = (query, options, transformer) => { let iconURI = markerParts[1]; // Check if icon is served via http otherwise marker icons are expected to // be provided as filepaths relative to configured icon path - if (!(iconURI.startsWith('http://') || iconURI.startsWith('https://'))) { + const isRemoteURL = + iconURI.startsWith('http://') || iconURI.startsWith('https://'); + const isDataURL = iconURI.startsWith('data:'); + if (!(isRemoteURL || isDataURL)) { // Sanitize URI with sanitize-filename // https://www.npmjs.com/package/sanitize-filename#details iconURI = sanitize(iconURI); @@ -292,7 +295,9 @@ const extractMarkersFromQuery = (query, options, transformer) => { iconURI = path.resolve(options.paths.icons, iconURI); // When we encounter a remote icon check if the configuration explicitly allows them. - } else if (options.allowRemoteMarkerIcons !== true) { + } else if (isRemoteURL && options.allowRemoteMarkerIcons !== true) { + continue; + } else if (isDataURL && options.allowInlineMarkerImages !== true) { continue; } From 9d5684513e47fedcce9863e11843e0a12aa01bff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 22:41:05 +0000 Subject: [PATCH 2/4] fix(deps): Bump commander from 11.0.0 to 11.1.0 (#1014) Bumps [commander](https://github.com/tj/commander.js) from 11.0.0 to 11.1.0. - [Release notes](https://github.com/tj/commander.js/releases) - [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/tj/commander.js/compare/v11.0.0...v11.1.0) --- updated-dependencies: - dependency-name: commander dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 17 +++++++++++++---- package.json | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 73e6605..90e247e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "chokidar": "3.5.3", "clone": "2.1.2", "color": "4.2.3", - "commander": "11.0.0", + "commander": "11.1.0", "cors": "2.8.5", "express": "4.18.2", "handlebars": "4.7.8", @@ -2141,9 +2141,9 @@ } }, "node_modules/commander": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", - "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "engines": { "node": ">=16" } @@ -4830,6 +4830,15 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/lint-staged/node_modules/commander": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", + "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, "node_modules/lint-staged/node_modules/execa": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", diff --git a/package.json b/package.json index d1b3139..57f227d 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "chokidar": "3.5.3", "clone": "2.1.2", "color": "4.2.3", - "commander": "11.0.0", + "commander": "11.1.0", "cors": "2.8.5", "express": "4.18.2", "handlebars": "4.7.8", From 3781054f2db99982a6ed9a5af244cfb08d4c80bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 23:05:24 +0000 Subject: [PATCH 3/4] fix(deps): Bump proj4 from 2.9.0 to 2.9.1 (#1015) Bumps [proj4](https://github.com/proj4js/proj4js) from 2.9.0 to 2.9.1. - [Release notes](https://github.com/proj4js/proj4js/releases) - [Changelog](https://github.com/proj4js/proj4js/blob/master/changelog.md) - [Commits](https://github.com/proj4js/proj4js/compare/2.9.0...2.9.1) --- updated-dependencies: - dependency-name: proj4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 90e247e..007f2d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "http-shutdown": "1.2.2", "morgan": "1.10.0", "pbf": "3.2.1", - "proj4": "2.9.0", + "proj4": "2.9.1", "request": "2.88.2", "sanitize-filename": "1.6.3", "sharp": "0.32.6", @@ -6741,12 +6741,12 @@ } }, "node_modules/proj4": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.9.0.tgz", - "integrity": "sha512-BoDXEzCVnRJVZoOKA0QHTFtYoE8lUxtX1jST38DJ8U+v1ixY70Kpwi0Llu6YqSWEH2xqu4XMEBNGcgeRIEywoA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.9.1.tgz", + "integrity": "sha512-hhquvYHnqz8nf8U9CODRLGSL7bUg4p5oVkZI4oWxX7whNcSbn2xdNA1WnF1jye+ezrtuSiPVao9LEHlKeQA5uA==", "dependencies": { "mgrs": "1.0.0", - "wkt-parser": "^1.3.1" + "wkt-parser": "^1.3.3" } }, "node_modules/promise-inflight": { @@ -8702,9 +8702,9 @@ } }, "node_modules/wkt-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.3.2.tgz", - "integrity": "sha512-A26BOOo7sHAagyxG7iuRhnKMO7Q3mEOiOT4oGUmohtN/Li5wameeU4S6f8vWw6NADTVKljBs8bzA8JPQgSEMVQ==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.3.3.tgz", + "integrity": "sha512-ZnV3yH8/k58ZPACOXeiHaMuXIiaTk1t0hSUVisbO0t4RjA5wPpUytcxeyiN2h+LZRrmuHIh/1UlrR9e7DHDvTw==" }, "node_modules/wordwrap": { "version": "1.0.0", diff --git a/package.json b/package.json index 57f227d..3808d84 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "http-shutdown": "1.2.2", "morgan": "1.10.0", "pbf": "3.2.1", - "proj4": "2.9.0", + "proj4": "2.9.1", "request": "2.88.2", "sanitize-filename": "1.6.3", "sharp": "0.32.6", From e8f64e2861a79a1e708934e4e0e9647140148451 Mon Sep 17 00:00:00 2001 From: Martin d'Allens Date: Sat, 14 Oct 2023 01:08:28 +0200 Subject: [PATCH 4/4] chore: cleanup useless decodeURIComponent() calls (#1002) * chore: cleanup useless decodeURIComponent() calls Signed-off-by: Martin d'Allens * chore: try to fix CodeQL failure "Polynomial regular expression" Fix 1: \d\.?\d* can backtrack catastrophically \d(\.\d*)? is safer Fix 2: Useless parenthesis around "enc:" Fix 3: The httpTester regex was misleading. It did not really check for "http". Simplified to show its true meaning. The behaviour should not have changed. Signed-off-by: Martin d'Allens * chore: try to optimize the regex further, to fix CodeQL failure Signed-off-by: Martin d'Allens * chore: consistency between previous changes, docs, and serve_style.js Signed-off-by: Martin d'Allens --------- Signed-off-by: Martin d'Allens --- docs/endpoints.rst | 4 ++-- src/serve_rendered.js | 11 ++++------- src/serve_style.js | 2 +- test/static.js | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/docs/endpoints.rst b/docs/endpoints.rst index 6dcb5ab..cfed7f0 100644 --- a/docs/endpoints.rst +++ b/docs/endpoints.rst @@ -35,7 +35,7 @@ Static images * All the static image endpoints additionally support following query parameters: - * ``path`` - ``((fill|stroke|width)\:[^\|]+\|)*((enc:.+)|((-?\d+\.?\d*,-?\d+\.?\d*\|)+(-?\d+\.?\d*,-?\d+\.?\d*)))`` + * ``path`` - ``((fill|stroke|width)\:[^\|]+\|)*(enc:.+|-?\d+(\.\d*)?,-?\d+(\.\d*)?(\|-?\d+(\.\d*)?,-?\d+(\.\d*)?)+)`` * comma-separated ``lng,lat``, pipe-separated pairs @@ -50,7 +50,7 @@ Static images * e.g. ``path=stroke:yellow|width:2|fill:green|5.9,45.8|5.9,47.8|10.5,47.8|10.5,45.8|5.9,45.8`` or ``path=stroke:blue|width:1|fill:yellow|enc:_p~iF~ps|U_ulLnnqC_mqNvxq`@`` - * can be provided multiple times + * can be provided multiple times * ``latlng`` - indicates coordinates are in ``lat,lng`` order rather than the usual ``lng,lat`` * ``fill`` - color to use as the fill (e.g. ``red``, ``rgba(255,255,255,0.5)``, ``#0000ff``) diff --git a/src/serve_rendered.js b/src/serve_rendered.js index 78648d5..c3ce22a 100644 --- a/src/serve_rendered.js +++ b/src/serve_rendered.js @@ -22,8 +22,8 @@ import { getFontsPbf, getTileUrls, fixTileJSONCenter } from './utils.js'; const FLOAT_PATTERN = '[+-]?(?:\\d+|\\d+.?\\d+)'; const PATH_PATTERN = - /^((fill|stroke|width)\:[^\|]+\|)*((enc:.+)|((-?\d+\.?\d*,-?\d+\.?\d*\|)+(-?\d+\.?\d*,-?\d+\.?\d*)))/; -const httpTester = /^(http(s)?:)?\/\//; + /^((fill|stroke|width)\:[^\|]+\|)*(enc:.+|-?\d+(\.\d*)?,-?\d+(\.\d*)?(\|-?\d+(\.\d*)?,-?\d+(\.\d*)?)+)/; +const httpTester = /^\/\//; const mercator = new SphericalMercator(); const getScale = (scale) => (scale || '@1x').slice(1, 2) | 0; @@ -158,10 +158,7 @@ const extractPathsFromQuery = (query, transformer) => { // Iterate through paths, parse and validate them for (const providedPath of providedPaths) { // Logic for pushing coords to path when path includes google polyline - if ( - providedPath.includes('enc:') && - PATH_PATTERN.test(decodeURIComponent(providedPath)) - ) { + if (providedPath.includes('enc:') && PATH_PATTERN.test(providedPath)) { // +4 because 'enc:' is 4 characters, everything after 'enc:' is considered to be part of the polyline const encIndex = providedPath.indexOf('enc:') + 4; const coords = polyline @@ -432,7 +429,7 @@ const drawMarkers = async (ctx, markers, z) => { * @param {number} z Map zoom level. */ const drawPath = (ctx, path, query, pathQuery, z) => { - const splitPaths = decodeURIComponent(pathQuery).split('|'); + const splitPaths = pathQuery.split('|'); if (!path || path.length < 2) { return null; diff --git a/src/serve_style.js b/src/serve_style.js index 3620018..c8b7265 100644 --- a/src/serve_style.js +++ b/src/serve_style.js @@ -9,7 +9,7 @@ import { validate } from '@maplibre/maplibre-gl-style-spec'; import { getPublicUrl } from './utils.js'; -const httpTester = /^(http(s)?:)?\/\//; +const httpTester = /^\/\//; const fixUrl = (req, url, publicUrl, opt_nokey) => { if (!url || typeof url !== 'string' || url.indexOf('local://') !== 0) { diff --git a/test/static.js b/test/static.js index 302becb..32bd80c 100644 --- a/test/static.js +++ b/test/static.js @@ -180,7 +180,7 @@ describe('Static endpoints', function () { 200, 2, /image\/png/, - '?path=' + decodeURIComponent('enc:{{biGwvyGoUi@s_A|{@'), + '?path=' + encodeURIComponent('enc:{{biGwvyGoUi@s_A|{@'), ); }); });