maptool icon indicating copy to clipboard operation
maptool copied to clipboard

[Bug]: Quotations dropped of JSON string passed to JavaScript

Open fw opened this issue 1 year ago • 5 comments

Describe the Bug

In particular cases, quotations of JSON string are dropped when that is passed to JavaScript.

The cases I found:

  • Set JSON string to a variable.
  • Pass JSON string that is created by "json.append" to JS function as an argument.

To Reproduce

Create a "Lib:Test" token. Create three macros below on that token and run the "RUN" macro.

javascript

function sendBack(value) {
	return value;
}
MTScript.registerMacro("sendBack", sendBack);

onCampaignLoad

[r: js.evalURI("test", "lib://Test/macro/javascript")]

RUN

<pre>
<b>Pass JSON array to js function by inline</b>
getSelected: [r: js.sendBack(getSelected("json"))]
json.append: [r: js.sendBack(json.append("[]", "foo"))]
string: [r: js.sendBack('["foo"]')]

<b>Pass JSON array to js function via variable</b>
[h: s1 = getSelected("json")     ]getSelected: [r: js.sendBack(s1)]
[h: s2 = json.append("[]", "foo")]json.append: [r: js.sendBack(s2)]
[h: s3 = '["foo"]'               ]string: [r: js.sendBack(s3)]

<b>MT function output</b>
getSelected: [r: s1]
json.append: [r: s2]
string: [r: s3]

<b>Pass JSON object to js function by inline</b>
json.set: [r: js.sendBack(json.set("{}", "foo", "bar"))]
string: [r: js.sendBack('{"foo":"bar"}')]

<b>Pass JSON object to js function via variable</b>
[h: s4 = json.set("{}", "foo", "bar")]json.set: [r: js.sendBack(s4)]
[h: s5 = '{"foo":"bar"}'             ]string: [r: js.sendBack(s5)]

<b>MT function output</b>
json.set: [r: s4]
string: [r: s5]
</pre>

Outpu on v1.12.0-beta.1:

Pass JSON array to js function by inline
getSelected: ["A7962B0927A64ACF93E98DDCA25B79B5"]
json.append: [foo]
string: ["foo"]

Pass JSON array to js function via variable
getSelected: [A7962B0927A64ACF93E98DDCA25B79B5]
json.append: [foo]
string: [foo]

MT function output
getSelected: ["A7962B0927A64ACF93E98DDCA25B79B5"]
json.append: ["foo"]
string: ["foo"]

Pass JSON object to js function by inline
json.set: {foo=bar}
string: {"foo":"bar"}

Pass JSON object to js function via variable
json.set: {foo=bar}
string: {foo=bar}

MT function output
json.set: {"foo":"bar"}
string: {"foo":"bar"}

Sample campaign file: quotations-dropped.zip

Expected Behaviour

I expected the result below (this is run on v1.11.4).

Pass JSON array to js function by inline
getSelected: ["A7962B0927A64ACF93E98DDCA25B79B5"]
json.append: ["foo"]
string: ["foo"]

Pass JSON array to js function via variable
getSelected: ["A7962B0927A64ACF93E98DDCA25B79B5"]
json.append: ["foo"]
string: ["foo"]

MT function output
getSelected: ["A7962B0927A64ACF93E98DDCA25B79B5"]
json.append: ["foo"]
string: ["foo"]

Pass JSON object to js function by inline
json.set: {"foo":"bar"}
string: {"foo":"bar"}

Pass JSON object to js function via variable
json.set: {"foo":"bar"}
string: {"foo":"bar"}

MT function output
json.set: {"foo":"bar"}
string: {"foo":"bar"}

Screenshots

No response

MapTool Info

MapTool 1.12.0-beta.1

Desktop

Windows 10 Pro

Additional Context

No response

fw avatar Aug 08 '22 20:08 fw

Is this new behavior for 1.12.0 beta 1?

Phergus avatar Aug 08 '22 20:08 Phergus

I have only tested 1.11.4 and 1.12.0-beta.1 at posted this issue. Installing 1.11.5 and 1.12.0-alpha.1 and checking this issue now, I get the same behavior at v1.12.0-alpha.1.

fw avatar Aug 09 '22 08:08 fw

Thanks.

Phergus avatar Aug 09 '22 15:08 Phergus

This looks like the intended behavior. MT prior to 1.8 had a nashorn-based javascript engine that saw limited use. When we replaced it wil graalvm and started advertising it, we tried to keep it as fully compatible with the nashorn implementation as possible, warts and all. For context, see #2519 .

That said, we've since made some significant changes to the way javascript interacts with maptool, such that keeping perfect compatibility with the old nashorn oddities probably doesn't matter as much, so revisiting some of this might make sense. On the other hand, I don't know how important improving the js->mtscript conversions really is, vs spending the effort reducing the need of mtscript in the first place.

perkinslr avatar Aug 09 '22 22:08 perkinslr

I tested it in newer versions those are v1.14.3, and v1.15.0-beta.1. Then I got the following result.

I think it is essentially considered correct if it has no problems that there are or aren't indentations.

Pass JSON array to js function by inline
getSelected: ["E0F1F064D10546EBB4EC39A355231C9E"]
json.append: [
  "foo"
]
string: ["foo"]

Pass JSON array to js function via variable
getSelected: [
  "E0F1F064D10546EBB4EC39A355231C9E"
]
json.append: [
  "foo"
]
string: [
  "foo"
]

MT function output
getSelected: ["E0F1F064D10546EBB4EC39A355231C9E"]
json.append: ["foo"]
string: ["foo"]

Pass JSON object to js function by inline
json.set: {
  "foo": "bar"
}
string: {"foo":"bar"}

Pass JSON object to js function via variable
json.set: {
  "foo": "bar"
}
string: {
  "foo": "bar"
}

MT function output
json.set: {"foo":"bar"}
string: {"foo":"bar"}

fw avatar Feb 18 '24 19:02 fw