| Ticket UUID: | 13d3c0d764fa4cf1c0cf0577924d7a0be5a3fd2b | ||
| Title: | lset on empty list is allowed when index argument is large | ||
| Type: | Bug | Created on: | 2023-08-13 15:47:58 |
| Submitter: | apnadkarni | Assigned to: | jan.nijtmans |
| Subsystem: | - New Builtin Commands | Severity: | Minor |
| Priority: | 5 Medium | Last modified: | 2026-11-01 16:58:39 |
| Status: | Closed | Closed by: | dkf |
| Resolution: | Fixed | Closed on: | 2026-11-01 16:58:39 |
| Version: | 9.0.5, 9.1.0 | ||
| Description: | ||||
|
When the list is empty, the index 0x7fffffffffffffff (or higher) is incorrectly treated as index 0 (i.e. just beyond last valid index). As the first line shows, smaller out of bounds indices are treated correctly. As the last line shows, this bug only occurs when the list is empty. Like bug bc076f4f0e, this bug was also introduced by commit 0b05b5c750df intended to fix TIP 577 issues in Tk. While this issue may be considered relatively minor, it points to what I think is a fundamental flaw in internal index encoding in Tcl: the number of values that need to be represented in an "index" are greater than the range of the index type, no matter whether 32- or 64-bits. This is due to non-negative integers being valid (for obvious reasons), negative integers being valid (as end-N) representation, which together occupy the entire domain. Then there is a need for additional values representing "end" and "one beyond end" for which there is no room necessitating hacks like this which is the cause of the above bug. Removing that hack will cause
which should be allowed. Changing the core indexing routines to fix this breaks Tk indexing for negative (in the C API) and end relative indices. Given the above limitation in range of values I see no way around this other than living with the above bug for 9.0. If I am wrong and anyone has a solution, please verify it works with both Tk and the bigdata tests for large indices. | ||||
| User Comments: | ||||
serhiy.storchaka added on 2026-10-17 16:03:05:
The ambiguity can be resolved locally in TclLsetFlat(), without changing the index encoding (so Tk is not affected): when the list is empty and the index comes back as TCL_SIZE_MAX, evaluate it again as if the list had one element, and accept it only if this gives 1 (end+1 and similar forms). Proposed fix in branch lset-empty-huge-index, tests lset-18.1 to lset-18.5. 8.6 is not affected. | ||||
