Tk Source Code

View Ticket
Login
Ticket UUID: 766ef52f317f3a4a31cfca65b17d79c1d0b8c20a
Title: option readfile loses list structure
Type: Bug Version: 8.6.6
Submitter: bigfaceworm Created on: 2018-05-30 02:38:10
Subsystem: 23. Option Parsing Assigned To: mistachkin
Priority: 5 Medium Severity: Important
Status: Open Last Modified: 2019-06-08 04:44:24
Resolution: Fixed Closed By: nobody
    Closed on: 2018-11-10 19:44:34
Description:
I'll include the test script.  But the english version of the bug is this.  With a value that is a list, the [option readfile ...] in Tcl 8.6.6 loses the list structure.  At least that's what it appears to do.  The same code preserves the list in 8.4.19, and [option add ...] preserves it as well (in both 8.4.19 and 8.6.6).

When run, the script prints out the value of the option (joined by \n) after adding the option directly and from reading the file, and only when reading the file in from the options file does it show up with an extra list element - splitting the first word and open { into different elements.

------------------------begin script--------------------------
#!/bin/sh
#-*-Tcl-*- the next line restarts using wish \
    exec wish  "$0" "$@"

# A script that shows that a defect in option readfile in Tcl8.6:
# Newlines are not retained from the options when read through the file

set option_content {label {
  foo bar
}
}

# need to split on newline in order to put content into options file
set content_list [split $::option_content \n]

# Put the option in directly
option add *direct $content_list

set direct_access [option get . direct direct]
# this looks the same in 8.4 and 8.6
puts DIRECT:
puts [join $direct_access \n]


set filename /tmp/tcl_
while {[file exists $filename]} {
  set chars abcdefghijklmnopqrstuvwxyz
  append filename [string index $chars [expr {int(rand() * [string length $chars])}]]
}

set channel [open $filename {RDWR CREAT EXCL}]
puts $channel "*notok: $content_list"
close $channel


# Read the option file
if {[catch {option readfile $filename userDefault} err]} {
    puts "Problem reading the file $filename: $err"
    exit
}
# Get the option
set read_from_file [option get . notok notok]

# Print the option. Notice the behavior difference between 8.4 and 8.6
# the 'label {' is one element in 8.4, but is two elements in 8.6
puts FROM_FILE:
puts [join $read_from_file \n]


exit
User Comments: mistachkin added on 2019-06-08 04:44:24:
Apparently, the fix for this was not quite right.

I think this will be difficult to solve in a way that both honors the X11
specification ( https://www.x.org/archive/X11R6.8.1/doc/X.7.html#sect13 )
and maintains backward compatibility with Tcl 8.4.

The root cause of the reported issue (i.e. not maintaining list structure)
appears to be the handling of the sequence "\<space>" (i.e. where "<space>"
is an actual space character).  Tcl uses this sequence to escape a space
within a list element; however, the (linked) X11 specification indicates
it is to be replaced with only the space.

I'm not sure how to resolve this yet.

mistachkin added on 2018-11-10 19:44:34:

Fixed on trunk via check-in [2322894eb8c65456].


mistachkin added on 2018-11-10 19:38:33:
Fixed on core-8-6-branch via check-in [5550a1383b7a98f9].

mistachkin added on 2018-11-08 16:47:31:
The changes on the branch are ready to be merged.

dgp added on 2018-11-08 16:13:39:
status?

Are we able to get this into 8.6.9 ?

fvogel added on 2018-10-19 19:43:07:

Joe Mistachkin proposed a fix [9bbc84a2], with and additional non-regression testcase [a3d5e096].