ExtendScript evaluates nested ternary operator with wrong (left) associativity
Component: ExtendScript engine (scripting). Affects Illustrator, likely all ExtendScript hosts.
Environment (confirmed):
Illustrator 30.8.2, ExtendScript 4.5.6, macOS 15.7.9
Illustrator CS6 16.0.0, ExtendScript 4.2.12, Windows
Old and new builds, both platforms.
Summary:
ExtendScript evaluates a nested conditional expression a ? b : c ? d : e as if it were left-associative, i.e. (a ? b : c) ? d : e, instead of the ECMAScript-required right-associative a ? b : (c ? d : e). ECMA-262 defines ConditionalExpression as right-associative, and this has been the case since the 3rd edition that ExtendScript targets. When any condition before the last is true, the result is the wrong branch, usually the final alternative.
Steps to reproduce:
Run a .jsx with #target illustrator (no document needed).
Execute:
Expected result: A, because the first condition is true.
Actual result: C.
Confirmation that associativity is the cause: the explicitly grouped form returns the correct value.
Systematic test: I ran all 8 boolean combinations of three conditions across nested, grouped and if/else variants, 24 cases in total, with expected values taken from fixed reference tables rather than from the expression under test. The nested ternary was wrong in 10 cases. The grouped ternary, the if/else chain and a lookup-object implementation were correct in all 24. I can attach the probe script if that helps.
Related, same parser: this is the second associativity/precedence issue I have found in the ExtendScript parser. The first one is here:
https://illustrator.uservoice.com/forums/601447-illustrator-desktop-bugs/suggestions/51776781-extendscript-gives-and-equal-precedence
In that one, && and || share a precedence level, so true || false && false returns false where ECMAScript requires true. Both issues reproduce on the same builds listed above, which suggests the expression parser rather than any individual operator.
Impact: code that is valid ECMAScript silently produces wrong results. It is particularly dangerous with minifiers, because Google Closure Compiler rewrites if/else-if chains into nested ternaries. Source that reads correctly then ships broken. In my case the script selected the wrong UI language for an end user, and the source had a plain if/else chain with no ternary in it at all.
Workaround: parenthesize nested ternaries explicitly, use if/else, or use a lookup object. For minified builds, a post-process step that parenthesizes nested ternaries is safe, since it is a no-op in standard ECMAScript.
Request: fix ConditionalExpression associativity and logical operator precedence in the ExtendScript parser to match ECMA-262.