Tcl Source Code

View Ticket
Login
Ticket UUID: 9c7557160fd1fb402aa1eb3ec4b358cfa79d596
Title: signed integer overflow in UpdateStringOfByteArray()
Type: Patch Version: core-8-6-branch
Submitter: chrstphrchvz Created on: 2022-02-18 20:07:21
Subsystem: 12. ByteArray Object Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2022-03-11 17:21:28
Resolution: Fixed Closed By: jan.nijtmans
    Closed on: 2022-03-11 17:21:28
Description:

int size overflowing when incremented is undefined behavior. Example script and output showing UBSan (-fsanitize=signed-integer-overflow) error:

set f [open /dev/zero [list RDONLY BINARY]]
fconfigure $f -buffersize [expr {2**20}]
set z [read $f [expr {2**30}]]
puts [::tcl::mathop::ni $z [list]]
tcl/generic/tclBinary.c:568:10: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
max size for a Tcl value (2147483647 bytes) exceeded
(tclsh aborted)

If size does not overflow, it could instead be INT_MAX, causing overflow in ckalloc(size + 1). Example script and output:

set f [open /dev/zero [list RDONLY BINARY]]
fconfigure $f -buffersize [expr {2**20}]
set a [encoding convertto utf-8 a]
set z [read $f [expr {2**30 - 1}]]
set az [string cat $a $z]
puts [::tcl::mathop::ni $az [list]]
tcl/generic/tclBinary.c:575:19: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
1

Casting size to unsigned int avoids this; see attached patch. (There could be alternatives such as declaring size as unsigned int.)

User Comments: jan.nijtmans added on 2022-03-11 17:21:28:

@dgp, I like your alternative! Just go ahead.


dgp added on 2022-03-11 16:49:11:
Alternative patch to consider found on bug-9c7557160f branch.

Leaves behind fewer typecasts for future code readers to puzzle over.

jan.nijtmans added on 2022-03-08 15:33:47:

Fixed [5e793d379a|here]. Thanks!


Attachments: