Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fixed memory corruption in case of scripted xpath function with an attribute as context node (reported by https://github.com/tDOM/tdom/issues/16).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d5664646d62588d0828c30d67a56c87e50ba91eb
User & Date: rolf 2013-08-16 14:59:28
Context
2013-08-17
12:49
Noted the TEA update in CHANGES. Declared Changelog as obsolete. check-in: 6c1a36e58f user: rolf tags: trunk
2013-08-16
14:59
Fixed memory corruption in case of scripted xpath function with an attribute as context node (reported by https://github.com/tDOM/tdom/issues/16). check-in: d5664646d6 user: rolf tags: trunk
2013-08-15
01:16
Test documenting the seg fault reported by https://github.com/tDOM/tdom/issues/16. check-in: 97f6f2f627 user: rolf tags: trunk
Changes

Changes to generic/tcldom.c.

1270
1271
1272
1273
1274
1275
1276
1277

1278
1279
1280
1281
1282
1283
1284
....
1300
1301
1302
1303
1304
1305
1306










1307
1308


1309
1310
1311
1312
1313
1314
1315
    xpathResultSet  *result,
    char           **errMsg
)
{
    Tcl_Interp  *interp = (Tcl_Interp*) clientData;
    char         tclxpathFuncName[200], objCmdName[80];
    char         *errStr, *typeStr, *nodeName;
    Tcl_Obj     *resultPtr, *objv[MAX_REWRITE_ARGS], *type, *value, *nodeObj;

    Tcl_CmdInfo  cmdInfo;
    int          objc, rc, i, errStrLen, listLen, intValue, res;
    double       doubleValue;
    domNode     *node;

    DBG(fprintf(stderr, "tcldom_xpathFuncCallBack functionName=%s "
                "position=%d argc=%d\n", functionName, position, argc);)
................................................................................
    if ( (5+(2*argc)) >= MAX_REWRITE_ARGS) {
        *errMsg = (char*)tdomstrdup("too many args for Tcl level method!");
        return XPATH_EVAL_ERR;
    }
    objc = 0;
    objv[objc] = Tcl_NewStringObj(tclxpathFuncName, -1);
    Tcl_IncrRefCount(objv[objc++]);










    tcldom_createNodeObj(interp, ctxNode, objCmdName);
    objv[objc] = Tcl_NewStringObj(objCmdName, -1);


    Tcl_IncrRefCount(objv[objc++]);

    objv[objc] = Tcl_NewIntObj(position);
    Tcl_IncrRefCount(objv[objc++]);

    type  = Tcl_NewObj();
    value = Tcl_NewObj();







|
>







 







>
>
>
>
>
>
>
>
>
>
|
|
>
>







1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
....
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
    xpathResultSet  *result,
    char           **errMsg
)
{
    Tcl_Interp  *interp = (Tcl_Interp*) clientData;
    char         tclxpathFuncName[200], objCmdName[80];
    char         *errStr, *typeStr, *nodeName;
    Tcl_Obj     *resultPtr, *objv[MAX_REWRITE_ARGS], *type, *value, *nodeObj,
                *tmpObj;
    Tcl_CmdInfo  cmdInfo;
    int          objc, rc, i, errStrLen, listLen, intValue, res;
    double       doubleValue;
    domNode     *node;

    DBG(fprintf(stderr, "tcldom_xpathFuncCallBack functionName=%s "
                "position=%d argc=%d\n", functionName, position, argc);)
................................................................................
    if ( (5+(2*argc)) >= MAX_REWRITE_ARGS) {
        *errMsg = (char*)tdomstrdup("too many args for Tcl level method!");
        return XPATH_EVAL_ERR;
    }
    objc = 0;
    objv[objc] = Tcl_NewStringObj(tclxpathFuncName, -1);
    Tcl_IncrRefCount(objv[objc++]);
    if (ctxNode->nodeType == ATTRIBUTE_NODE) {
        tcldom_createNodeObj(interp, ((domAttrNode*)ctxNode)->parentNode,
                             objCmdName);
        tmpObj = Tcl_NewListObj(0, NULL);
        Tcl_ListObjAppendElement(interp, tmpObj, 
                                 Tcl_NewStringObj(objCmdName, -1));
        Tcl_ListObjAppendElement(
            interp, tmpObj,
            Tcl_NewStringObj(((domAttrNode*)ctxNode)->nodeName, -1));
    } else {
        tcldom_createNodeObj(interp, ctxNode, objCmdName);
        tmpObj = Tcl_NewStringObj(objCmdName, -1);
    }
    objv[objc] = tmpObj;
    Tcl_IncrRefCount(objv[objc++]);

    objv[objc] = Tcl_NewIntObj(position);
    Tcl_IncrRefCount(objv[objc++]);

    type  = Tcl_NewObj();
    value = Tcl_NewObj();

Changes to tests/xslt.test.

1145
1146
1147
1148
1149
1150
1151
1152




1153
1154
1155
1156
1157
1158
1159
....
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
    set xsltDoc [dom parse $xslt]
    set result [catch {$xmlDoc xslt $xsltDoc} errMsg]
    $xmlDoc delete
    $xsltDoc delete
    set result
} {1}

proc ::dom::xpathFunc::local_gmt {args} {




    return {string "bar"}
}

test xslt-9.1 {xslt using scripted xpath function} -setup {
    set xml {<a><b start="foo"><c/></b></a>}
    set xsl {<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        version="1.0">
................................................................................
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>         
  <xsl:template match="@start">
    <xsl:attribute name="start">
      <xsl:value-of select="local_gmt(.)"/>
    </xsl:attribute>
  </xsl:template>
</xsl:transform>}
    set xsltDoc [dom parse -keepEmpties $xsl]
    set xmlDoc [dom parse $xml]
} -body {
    $xmlDoc xslt $xsltDoc resultDoc
    $resultDoc asXML -indent none
} -cleanup {
    $xsltDoc delete
    $xmlDoc delete
    $resultDoc delete
} -result {<a><b start="foo"><c/></b></a>}

# Below is code, which replaces the dom cmd with a version, which parses
# the xml into a dom tree, then transformations this dom tree with the
# xslt identity transformation and returns the result tree of that
# transformation. This is used to test, that the result tree of an xslt
# transformation could be used as any 'ordinary' tree created with
# [dom parse]. It is here, because I didn't want to hold it seperated.







|
>
>
>
>







 







|












|







1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
....
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
    set xsltDoc [dom parse $xslt]
    set result [catch {$xmlDoc xslt $xsltDoc} errMsg]
    $xmlDoc delete
    $xsltDoc delete
    set result
} {1}

proc ::dom::xpathFunc::xslt-9.1 {ctxNode pos nodeListType nodeList args} {
    if {[llength $ctxNode] != 2} {
        error "::dom::xpathFunc::xslt-9.1: expected parent node / attribute \
               name list as first argument."
    }
    return {string "bar"}
}

test xslt-9.1 {xslt using scripted xpath function} -setup {
    set xml {<a><b start="foo"><c/></b></a>}
    set xsl {<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        version="1.0">
................................................................................
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>         
  <xsl:template match="@start">
    <xsl:attribute name="start">
      <xsl:value-of select="xslt-9.1(.)"/>
    </xsl:attribute>
  </xsl:template>
</xsl:transform>}
    set xsltDoc [dom parse -keepEmpties $xsl]
    set xmlDoc [dom parse $xml]
} -body {
    $xmlDoc xslt $xsltDoc resultDoc
    $resultDoc asXML -indent none
} -cleanup {
    $xsltDoc delete
    $xmlDoc delete
    $resultDoc delete
} -result {<a><b start="bar"><c/></b></a>}

# Below is code, which replaces the dom cmd with a version, which parses
# the xml into a dom tree, then transformations this dom tree with the
# xslt identity transformation and returns the result tree of that
# transformation. This is used to test, that the result tree of an xslt
# transformation could be used as any 'ordinary' tree created with
# [dom parse]. It is here, because I didn't want to hold it seperated.