Tcl Source Code

View Ticket
Login
Ticket UUID: 1965787
Title: 8.5.2 "tell" returns neg 32-bit value for positions > 2GB
Type: Bug Version: obsolete: 8.5.2
Submitter: nobody Created on: 2008-05-17 03:57:10
Subsystem: 24. Channel Commands Assigned To: andreas_kupries
Priority: 9 Immediate Severity:
Status: Closed Last Modified: 2008-05-24 04:34:36
Resolution: Accepted Closed By: andreas_kupries
    Closed on: 2008-05-23 21:34:36
Description:
Tcl "tell" command returned 64-bit unsigned values starting in 8.4 for use in managing files >2GB.

Tcl "tell" command in 8.5.2 seems to be returning a signed value which appears "negative" and unsuitable for use in Tcl "seek" command for file positions > 2GB.

Platform: XP-SP2, builds built locally with VC++ 2008 Express, also the distributed Equi4 "tclkit" for 8.5.2 produce this output:

(2008) 3 % set tcl_patchLevel
8.5.2
(2008) 4 % set fn "whopper.bin"
whopper.bin
(2008) 5 % file stat $fn s
(2008) 6 % set s(size)
3974747277
(2008) 7 % set f [open $fn "rb"]
fileb54c58
(2008) 8 % seek $f 2147016079
(2008) 9 % tell $f
2147016079
(2008) 10 % read $f 1000000 ; set x
can't read "x": no such variable
(2008) 11 % tell $f
-2146951217
(2008) 12 % seek $f 3974747000
(2008) 13 % tell $f
-320220296

By comparison (same platform):
(2008) 11 % set tcl_patchLevel
8.4.4
(2008) 12 % set fn "whopper.bin"
whopper.bin
(2008) 13 % file stat $fn s
(2008) 14 % set s(size)
3974747277
(2008) 15 % set f [open $fn "r"] ; fconfigure $f -translation binary
(2008) 16 % set f
file9bd888
(2008) 17 % seek $f 2147016079
(2008) 18 % tell $f
2147016079
(2008) 19 % read $f 1000000 ; set x
can't read "x": no such variable
(2008) 20 % tell $f
2148016079
(2008) 21 % seek $f 3974747000
(2008) 22 % tell $f
3974747000
(2008) 23 % 

David Burns : consollidator<AT>yahoo.com
User Comments: andreas_kupries added on 2008-05-24 04:34:36:
Logged In: YES 
user_id=75003
Originator: NO

Committed to Tcl 8.4 branch.
Committed to Tcl 8.5 branch.
Committed to Tcl Head branch.

ferrieux added on 2008-05-23 04:36:21:

File Added - 278728: wideseek.patch

Logged In: YES 
user_id=496139
Originator: NO

Found and fixed (attached patch).
The problem is the sign-extending int32->int64 conversion Tcl_LongAsWide, done on the low-order part of the tell value, which is a signed int32. To circumvent this I have replaced the use of the Tcl_LongAsWide macro by the more explicit cast:

  ((Tcl_WideInt)((unsigned)value))

Test suite passed.
This should work on 64-bit Windows, though I have now way to check.
Also notice that generating a test case is not easy since a file slightly over 2G is neede :-(

File Added: wideseek.patch

ferrieux added on 2008-05-23 03:40:18:

File Added - 278721: wideseek.patch

Logged In: YES 
user_id=496139
Originator: NO

Found and fixed (attached patch).
The problem is the sign-extending int32->int64 conversion Tcl_LongAsWide, done on the low-order part of the tell value, which is a signed int32. To circumvent this I have replaced the use of the Tcl_LongAsWide macro by the more explicit cast:

  ((Tcl_WideInt)((unsigned)value))

Test suite passed.
This should work on 64-bit Windows, though I have now way to check.
Also notice that generating a test case is not easy since a file slightly over 2G is neede :-(

File Added: wideseek.patch

Attachments: