Select to view content in your preferred language

Bad escaped character in JSON: esriConfig

1938
2
12-01-2023 07:59 AM
René_Ténière
Occasional Contributor

Hi all,

I am receiving multiple worker exceptions when the mapview loads. It does not affect anything as I believe the issue is in logger.

My site supports locale and config as querystring parameters. Adding the config parameter seems to trigger the issue. Example: http://localhost:5173/?locale=fr&config=assets\config\config.json causes the issue but http://localhost:5173/?locale=fr does not. I have also tried http://localhost:5173/?locale=fr&config=assets%5cconfig%5cconfig.json but that made no difference. My config file still loads up fine in the javascript either way.

Ren_Tnire_0-1701446021386.png

let globalId=0;const outgoing=new Map,configuration=JSON.parse('{"esriConfig":{"applicationName":"","applicationUrl":"http://localhost:5173/?locale=fr&config=assets\\config\\config.json","assetsPath":"https://js.arcgis.com/4.28/@arcgis/core/assets","fontsUrl":"https://static.arcgis.com/fonts","geometryServiceUrl":"https://utility.arcgisonline.com/arcgis/rest/services/Geometry/GeometryServer","geoRSSServiceUrl":"https://utility.arcgis.com/sharing/rss","kmlServiceUrl":"https://utility.arcgis.com/sharing/kml","userPrivilegesApplied":true,"portalUrl":"https://nsdnr-forestry.maps.arcgis.com","routeServiceUrl":"https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World","workers":{"loaderConfig":{"has":{},"paths":{},"map":{},"packages":[]},"workerPath":"https://js.arcgis.com/4.28/@arcgis/core/assets/esri/core/workers/RemoteClient.js","useDynamicImport":false},"request":{"crossOriginNoCorsDomains":null,"httpsDomains":["arcgis.com","arcgisonline.com","esrikr.com","premiumservices.blackbridge.com","esripremium.accuweather.com","gbm.digitalglobe.com","firstlook.digitalglobe.com","msi.digitalglobe.com"],"interceptors":[],"maxUrlLength":2000,"priority":"high","proxyRules":[],"proxyUrl":null,"timeout":60000,"trustedServers":[],"useIdentity":true},"log":{"interceptors":[],"level":null},"defaultAssetsPath":"https://js.arcgis.com/4.28/@arcgis/core/assets","locale":"fr","has":{"esri-csp-restrictions":false,"esri-2d-debug":false,"featurelayer-pbf":true,"featurelayer-simplify-thresholds":[0.5,0.5,0.5,0.5],"featurelayer-simplify-payload-size-factors":[1,1,4],"esri-atomics":true,"esri-shared-array-buffer":false,"esri-workers-arraybuffer-transfer":true,"feature-polyline-generalization-factor":1,"host-webworker":1}},"loaderConfig":{"async":true,"isDebug":false,"locale":"fr","has":{"csp-restrictions":1,"dojo-test-sniff":0,"host-webworker":1},"map":{},"packages":[],"paths":{}},"kernelInfo":{"buildDate":"20231115","fullVersion":"4.28.10","revision":"a6fcf2901ef678ef17a528e11b93ffe09e3ec267"}}');self.esriConfig=configuration.esriConfig;const workerPath=self.esriConfig.workers.workerPath,HANDSHAKE=0,OPEN=1,OPENED=2,RESPONSE=3,INVOKE=4,ABORT=5;function createAbortError(){const e=new Error("Aborted");return e.name="AbortError",e}function receiveMessage(e){return e&&e.data?"string"==typeof e.data?JSON.parse(e.data):e.data:null}function invokeStaticMessage(e,o,r){const t=r&&r.signal,n=globalId++;return new Promise(((r,s)=>{if(t){if(t.aborted)return s(createAbortError());t.addEventListener("abort",(()=>{outgoing.get(n)&&(outgoing.delete(n),self.postMessage({type:ABORT,jobId:n}),s(createAbortError()))}))}outgoing.set(n,{resolve:r,reject:s}),self.postMessage({type:INVOKE,jobId:n,methodName:e,abortable:null!=t,data:o})}))}let workerRevisionChecked=!1;function checkWorkerRevision(e){if(!workerRevisionChecked&&e.kernelInfo){workerRevisionChecked=!0;const{revision:o,fullVersion:r}=configuration.kernelInfo,{revision:t,fullVersion:n,version:s}=e.kernelInfo;esriConfig.assetsPath!==esriConfig.defaultAssetsPath&&o!==t&&console.warn(`Version mismatch detected between ArcGIS Maps SDK for JavaScript modules and assets. For more information visit https://bit.ly/3QnsuSo.\nModules version: ${r}\nAssets version: ${n??s}\nAssets path: ${esriConfig.assetsPath}`)}}function messageHandler(e){const o=receiveMessage(e);if(!o)return;const r=o.jobId;switch(o.type){case OPEN:let n;function t(e){const o=n.connect(e);self.postMessage({type:OPENED,jobId:r,data:o},[o])}"function"==typeof define&&define.amd?require([workerPath],(e=>{n=e.default||e,checkWorkerRevision(n),n.loadWorker(o.modulePath).then((e=>e||new Promise((e=>{require([o.modulePath],e)})))).then(t)})):"System"in self&&"function"==typeof System.import?System.import(workerPath).then((e=>(n=e.default,checkWorkerRevision(n),n.loadWorker(o.modulePath)))).then((e=>e||System.import(o.modulePath))).then(t):esriConfig.workers.useDynamicImport?import(workerPath).then((e=>{n=e.default||e,checkWorkerRevision(n),n.loadWorker(o.modulePath).then((e=>e||import(o.modulePath))).then(t)})):(self.RemoteClient||importScripts(workerPath),n=self.RemoteClient.default||self.RemoteClient,checkWorkerRevision(n),n.loadWorker(o.modulePath).then(t));break;case RESPONSE:if(outgoing.has(r)){const s=outgoing.get(r);outgoing.delete(r),o.error?s.reject(JSON.parse(o.error)):s.resolve(o.data)}}}self.dojoConfig=configuration.loaderConfig,esriConfig.workers.loaderUrl&&(self.importScripts(esriConfig.workers.loaderUrl),"function"==typeof require&&"function"==typeof require.config&&require.config(configuration.loaderConfig)),self.addEventListener("message",messageHandler),self.postMessage({type:0});

 

0 Kudos
2 Replies
JoelBennett
MVP Regular Contributor

The backslash in a JavaScript string is an escape character that is combined with the character immediately following it to represent a special character, for example \n is a newline character, and \t is a tab character.  The parser sees the backslashes in your value, but \c isn't a valid character.

 

To get around this, you need to escape your backslashes so that the compiler interprets them properly.  For instance "assets\config\config.json" should instead be "assets\\config\\config.json".  You can do this with something like:

var urlParams = new URLSearchParams(window.location.search);
var configPath = urlParams.get("config").replace(/\\/g, "\\\\");

 

0 Kudos
René_Ténière
Occasional Contributor

The url parameter is decoded properly within code (decodeURI() will properly return the escaped parameter). The issue is that you cannot rely on user validation. Upon further digging I have found that the applicationUrl is not uri encoded when added to the esriConfig: 

JSON.parse('{"esriConfig":{"applicationName":"","applicationUrl":"http://localhost:5173/?locale=fr&config=assets\\config\\config.json",

 JSON.parse() does not seem to accept an escaped \ (\\).

If the input URL is:

http://localhost:5173/?locale=fr&config=assets%5cconfig%5cconfig.json

 then there is no problem.

It would be proper if esri fixed the code that adds applicationUrl so that it is properly encoded, i.e. encodeURI(window.location.href). You cannot rely on the fact that the client will validate the url parameter. If you look at past WAB functionality, it accepted non-encoded or escaped backslashes as config parameters.