Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | [2992970] Restore safety of Tcl_AppendObjToObj(x, x) for bytearrays. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
704897a19b279eea0cbcf4fdd01e2bba |
User & Date: | dgp 2014-01-21 17:25:41 |
Context
2014-01-21
| ||
18:17 | merge mark check-in: 345437b24b user: dgp tags: trunk | |
17:25 | [2992970] Restore safety of Tcl_AppendObjToObj(x, x) for bytearrays. check-in: 704897a19b user: dgp tags: trunk | |
2014-01-15
| ||
19:04 | [2992970] Restore the safety of Tcl_AppendObjToObj(x, x) for bytearrays. Also moves overflow checkin... Closed-Leaf check-in: e5267e9dcd user: dgp tags: bug-2992970 | |
2014-01-08
| ||
11:04 | Make DEFAULT_TRIM_SET a MODULE_SCOPE string constant, so its value can be shared in tclCmdMZ.o and T... check-in: 2191bd8485 user: jan.nijtmans tags: trunk | |
Changes
Changes to generic/tclBinary.c.
︙ | ︙ | |||
606 607 608 609 610 611 612 | /* *---------------------------------------------------------------------- * * TclAppendBytesToByteArray -- * * This function appends an array of bytes to a byte array object. Note * that the object *must* be unshared, and the array of bytes *must not* | | < < > > > > > > > > > > | < | > < | < < < < < < | | < < | < > > > > > | | < < | > | < < < < | < | < < < < | < > | | < | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | /* *---------------------------------------------------------------------- * * TclAppendBytesToByteArray -- * * This function appends an array of bytes to a byte array object. Note * that the object *must* be unshared, and the array of bytes *must not* * refer to the object being appended to. * * Results: * None. * * Side effects: * Allocates enough memory for an array of bytes of the requested total * size, or possibly larger. [Bug 2992970] * *---------------------------------------------------------------------- */ void TclAppendBytesToByteArray( Tcl_Obj *objPtr, const unsigned char *bytes, int len) { ByteArray *byteArrayPtr; int needed; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray"); } if (len < 0) { Tcl_Panic("%s must be called with definite number of bytes to append", "TclAppendBytesToByteArray"); } if (len == 0) { /* Append zero bytes is a no-op. */ return; } if (objPtr->typePtr != &tclByteArrayType) { SetByteArrayFromAny(NULL, objPtr); } byteArrayPtr = GET_BYTEARRAY(objPtr); if (len > INT_MAX - byteArrayPtr->used) { Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); } needed = byteArrayPtr->used + len; /* * If we need to, resize the allocated space in the byte array. */ if (needed > byteArrayPtr->allocated) { ByteArray *ptr = NULL; int attempt; if (needed <= INT_MAX/2) { /* Try to allocate double the total space that is needed. */ attempt = 2 * needed; ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); } if (ptr == NULL) { /* Try to allocate double the increment that is needed (plus). */ unsigned int limit = INT_MAX - needed; unsigned int extra = len + TCL_MIN_GROWTH; int growth = (int) ((extra > limit) ? limit : extra); attempt = needed + growth; ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); } if (ptr == NULL) { /* Last chance: Try to allocate exactly what is needed. */ attempt = needed; ptr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt)); } byteArrayPtr = ptr; byteArrayPtr->allocated = attempt; SET_BYTEARRAY(objPtr, byteArrayPtr); } if (bytes) { memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len); } byteArrayPtr->used += len; TclInvalidateStringRep(objPtr); } /* *---------------------------------------------------------------------- * * TclInitBinaryCmd -- * |
︙ | ︙ |
Changes to generic/tclStringObj.c.
︙ | ︙ | |||
1277 1278 1279 1280 1281 1282 1283 | * Note that we only do this when the objects don't have string reps; if * it did, then appending the byte arrays together could well lose * information; this is a special-case optimization only. */ if ((TclIsPureByteArray(objPtr) || objPtr->bytes == tclEmptyStringRep) && TclIsPureByteArray(appendObjPtr)) { | < < > > > > > > > | > > > > | < > > > > | > > | | > | > > > > | | > | 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 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 | * Note that we only do this when the objects don't have string reps; if * it did, then appending the byte arrays together could well lose * information; this is a special-case optimization only. */ if ((TclIsPureByteArray(objPtr) || objPtr->bytes == tclEmptyStringRep) && TclIsPureByteArray(appendObjPtr)) { /* * You might expect the code here to be * * bytes = Tcl_GetByteArrayFromObj(appendObjPtr, &length); * TclAppendBytesToByteArray(objPtr, bytes, length); * * and essentially all of the time that would be fine. However, * it would run into trouble in the case where objPtr and * appendObjPtr point to the same thing. That may never be a * good idea. It seems to violate Copy On Write, and we don't * have any tests for the situation, since making any Tcl commands * that call Tcl_AppendObjToObj() do that appears impossible * (They honor Copy On Write!). For the sake of extensions that * go off into that realm, though, here's a more complex approach * that can handle all the cases. */ /* Get lengths */ int lengthSrc; (void) Tcl_GetByteArrayFromObj(objPtr, &length); (void) Tcl_GetByteArrayFromObj(appendObjPtr, &lengthSrc); /* Grow buffer enough for the append */ TclAppendBytesToByteArray(objPtr, NULL, lengthSrc); /* Reset objPtr back to the original value */ Tcl_SetByteArrayLength(objPtr, length); /* * Now do the append knowing that buffer growth cannot cause * any trouble. */ TclAppendBytesToByteArray(objPtr, Tcl_GetByteArrayFromObj(appendObjPtr, NULL), lengthSrc); return; } /* * Must append as strings. */ |
︙ | ︙ |