Project

Profile

Help

Bug #3134

map:get() key not being atomised

Added by John Lumley about 1 year ago. Updated 7 months ago.

Status:
Closed
Priority:
Normal
Sprint/Milestone:
-
Start date:
2017-02-16
Due date:
% Done:

100%

Applies to JS Branch:
1.0
Fix Committed on JS Branch:
1.0
Fixed in JS Release:
SEF Generated with:
Company:
-
Contact person:
-
Additional contact persons:
-

Description

In certain circumstances, proving difficult to isolate to a small sample, the argument to map:get() is not being atomised and the lookup fails with a 'TypeError: key.hashCode is not a function'.

The $m($node/@key) construct in:

 <xsl:variable name="node" as="element()">
   <a key="a"/>
 </xsl:variable>
 <xsl:sequence select="$m($node/@key)"/>

is compiled as:
 <ifCall xmlns:map="http://www.w3.org/2005/xpath-functions/map" line="92" name="map:get" type="item()*">
  <map size="1">
     <str val="a"/>
     <int val="27"/>
  </map>
  <atomSing line="88" diag="0|1||map:get">
   <slash simple="1">
      <elem name="a" namespaces="ixsl xp X p doc dc map saxon H err t f">
         <att name="key" flags="l">
            <str val="a"/>
          </att>
       </elem>
       <axis line="92" name="attribute" nodeTest="attribute(Q{}key)" jsTest="return item.name=='key'"/>
   </slash>
 </atomSing>
</ifCall>

where the attribute is atomised.

Deeper in the same stylesheet, using a tunneled variable, the $environments(t:environment/@ref) construct in:

 <xsl:variable name="environment" select="$environments(t:environment/@ref)"/>

is compiled to:
<ifCall xmlns:saxon="http://saxon.sf.net/" line="212" name="saxon:apply" type="item()*">
   <treat as="function(*)" jsTest="return SaxonJS.U.isMap(item) || SaxonJS.U.isArray(item);" diag="0|0||saxon:apply">
      <check card="1" diag="0|0||saxon:apply">
          <varRef name="environments" slot="0"/>
       </check>
   </treat>
   <arrayBlock>
       <slash>
          <axis name="child" nodeTest="element(Q{http://www.w3.org/2012/10/xslt-test-catalog}environment)" jsTest="var q=SaxonJS.U.nameOfNode(item); return item.nodeType==1 &amp;&amp; q.uri=='http://www.w3.org/2012/10/xslt-test-catalog'&amp;&amp;q.local=='environment';"/>
          <axis name="attribute" nodeTest="attribute(Q{}ref)" jsTest="return item.name=='ref'"/>
     </slash>
   </arrayBlock>
</ifCall>

which uses saxon:apply() and where there appears to be no compiled atomisation, so the node itself, which can't be hashed, is presented as the key. It does not appear from the Saxon-JS source that an atomisation check/operation happens between the saxon:apply() and the eventual map:get() invocation.

Obviously a temporary workround is to wrap the attribute reference with data() but this fault is a compliance failure.

History

#1 Updated by Debbie Lockett 9 months ago

  • Status changed from New to Resolved

Problem reproduced: XSLT3 TS tests maps-012 and maps-013 added (for function calls on maps and arrays).

The issue occurs when it has not been determined at compile time that a function call is being applied on a map. The fix is in the CoreFn applyFn function. Add key atomization before looking up.

#2 Updated by Debbie Lockett 7 months ago

  • Applies to branch deleted (9.8)
  • Applies to JS Branch 1.0 added
  • Fix Committed on JS Branch 1.0 added

#3 Updated by Debbie Lockett 7 months ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in JS Release set to Saxon-JS 1.0.1

Bug fix applied in Saxon-JS 1.0.1 maintenance release.

Please register to edit this issue

Also available in: Atom PDF Tracking page