Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge 8.6: Bug [9c5a00c69d]. Fix ~user on Windows |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | core-8-branch |
Files: | files | file ages | folders |
SHA3-256: |
a479ad913c8b46a4adc0089bb2ac5375 |
User & Date: | apnadkarni 2023-03-05 11:09:10.954 |
References
2024-12-09
| ||
08:03 | • New ticket [1dc7f3e5f1] filesystem-1.30.3 fails when HOME is under a symlink. artifact: 6383d25182 user: gahr | |
Context
2023-03-05
| ||
11:42 | Merge 8.7: Bug [9c5a00c69d]. Fix ~user on Windows check-in: 8c6befab7c user: apnadkarni tags: trunk, main | |
11:39 | A better fix for Valgrind "still reachable" report in TestcmdtokenCmd(). check-in: a42745193b user: pooryorick tags: core-8-branch | |
11:09 | Merge 8.6: Bug [9c5a00c69d]. Fix ~user on Windows check-in: a479ad913c user: apnadkarni tags: core-8-branch | |
09:57 | Bug [9c5a00c69d]. Fix ~user on Windows check-in: 82cc9a4f34 user: apnadkarni tags: core-8-6-branch | |
2023-03-04
| ||
16:26 | Protect zlib errors with check for null interp check-in: 626b25e226 user: apnadkarni tags: core-8-branch | |
Changes
Changes to tests/fCmd.test.
︙ | ︙ | |||
23 24 25 26 27 28 29 | testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testchmod [llength [info commands testchmod]] testConstraint winLessThan10 0 # Don't know how to determine this constraint correctly testConstraint notNetworkFilesystem 0 testConstraint reg 0 if {[testConstraint win]} { | | > > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testchmod [llength [info commands testchmod]] testConstraint winLessThan10 0 # Don't know how to determine this constraint correctly testConstraint notNetworkFilesystem 0 testConstraint reg 0 if {[testConstraint win]} { if {[catch { # Is the registry extension already static to this shell? try { load {} Registry set ::reglib {} } on error {} { # try the location given to use on the commandline to tcltest ::tcltest::loadTestedCommands load $::reglib Registry } testConstraint reg 1 } regError]} { catch {package require registry; testConstraint reg 1} } } testConstraint notInCIenv [expr {![info exists ::env(CI)] || !$::env(CI)}] # File permissions broken on wsl without some "exotic" wsl configuration testConstraint notWsl [expr {[llength [array names ::env *WSL*]] == 0}] set tmpspace /tmp;# default value # Find a group that exists on this Unix system, or else skip tests that |
︙ | ︙ | |||
95 96 97 98 99 100 101 102 103 104 105 106 107 108 | regexp {^[^(]*\(([^)]*)\)} [exec id] -> user } } if {$user eq ""} { set user "root" } } proc createfile {file {string a}} { set f [open $file w] puts -nonewline $f $string close $f return $string } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | regexp {^[^(]*\(([^)]*)\)} [exec id] -> user } } if {$user eq ""} { set user "root" } } # Try getting a lower case glob pattern that will match the home directory of # a given user to test ~user and [file tildeexpand ~user]. Note this may not # be the same as ~ even when "user" is current user. For example, on Unix # platforms ~ will return HOME envvar, but ~user will lookup password file # bypassing HOME. If home directory not found, returns *$user* so caller can # succeed by using glob matching under the hope that the path contains # the user name. proc gethomedirglob {user} { if {[testConstraint unix]} { if {![catch { exec {*}[auto_execok sh] -c "echo ~$user" } home]} { set home [string trim $home] if {$home ne ""} { # Expect exact match (except case), no glob * added return [string tolower $home] } } } elseif {[testConstraint reg]} { # Windows with registry extension loaded if {![catch { set sid [exec {*}[auto_execok powershell] -Command "(Get-LocalUser -Name '$user')\[0\].sid.Value"] set sid [string trim $sid] # Get path from the Windows registry set home [registry get "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\$sid" ProfileImagePath] set home [string trim $home] } result]} { if {$home ne ""} { # file join for \ -> / return [file join [string tolower $home]] } } } # Caller will need to use glob matching and hope user # name is in the home directory path return *$user* } proc createfile {file {string a}} { set f [open $file w] puts -nonewline $f $string close $f return $string } |
︙ | ︙ | |||
2598 2599 2600 2601 2602 2603 2604 | file home } -result relative/path test fCmd-31.6 {file home USER} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file home $::tcl_platform(user)] | | > > > > > > > | 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 | file home } -result relative/path test fCmd-31.6 {file home USER} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file home $::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] test fCmd-31.7 {file home UNKNOWNUSER} -body { file home nosuchuser } -returnCodes error -result {user "nosuchuser" doesn't exist} test fCmd-31.8 {file home extra arg} -body { file home $::tcl_platform(user) arg } -returnCodes error -result {wrong # args: should be "file home ?user?"} test fCmd-31.9 {file home USER does not follow env(HOME)} -setup { set ::env(HOME) [file join $::env(HOME) foo] } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -body { string tolower [file home $::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] test fCmd-32.1 {file tildeexpand ~} -body { file tildeexpand ~ } -result [file join $::env(HOME)] test fCmd-32.2 {file tildeexpand ~ - obeys env} -setup { set ::env(HOME) $::env(HOME)/xxx } -cleanup { |
︙ | ︙ | |||
2640 2641 2642 2643 2644 2645 2646 | file tildeexpand ~ } -result relative/path test fCmd-32.5 {file tildeexpand ~USER} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)] | | | | 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 | file tildeexpand ~ } -result relative/path test fCmd-32.5 {file tildeexpand ~USER} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] test fCmd-32.6 {file tildeexpand ~UNKNOWNUSER} -body { file tildeexpand ~nosuchuser } -returnCodes error -result {user "nosuchuser" doesn't exist} test fCmd-32.7 {file tildeexpand ~extra arg} -body { file tildeexpand ~ arg } -returnCodes error -result {wrong # args: should be "file tildeexpand path"} test fCmd-32.8 {file tildeexpand ~/path} -body { file tildeexpand ~/foo } -result [file join $::env(HOME)/foo] test fCmd-32.9 {file tildeexpand ~USER/bar} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)/bar] } -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar] test fCmd-32.10 {file tildeexpand ~UNKNOWNUSER} -body { file tildeexpand ~nosuchuser/foo } -returnCodes error -result {user "nosuchuser" doesn't exist} test fCmd-32.11 {file tildeexpand /~/path} -body { file tildeexpand /~/foo } -result /~/foo test fCmd-32.12 {file tildeexpand /~user/path} -body { |
︙ | ︙ | |||
2679 2680 2681 2682 2683 2684 2685 | file tildeexpand ~\\foo } -constraints win -result [file join $::env(HOME)/foo] test fCmd-32.16 {file tildeexpand ~USER\\bar} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)\\bar] | | > > > > > > > | 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 | file tildeexpand ~\\foo } -constraints win -result [file join $::env(HOME)/foo] test fCmd-32.16 {file tildeexpand ~USER\\bar} -body { # Note - as in 8.x this form does NOT necessarily give same result as # env(HOME) even when user is current user. Assume result contains user # name, else not sure how to check string tolower [file tildeexpand ~$::tcl_platform(user)\\bar] } -constraints win -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar] test fCmd-32.17 {file tildeexpand ~USER does not mirror HOME} -setup { set ::env(HOME) [file join $::env(HOME) foo] } -cleanup { set ::env(HOME) [file dirname $::env(HOME)] } -body { string tolower [file tildeexpand ~$::tcl_platform(user)] } -match glob -result [gethomedirglob $::tcl_platform(user)] # cleanup cleanup if {[testConstraint unix]} { removeDirectory tcl[pid] /tmp } |
︙ | ︙ |
Changes to tests/fileSystem.test.
︙ | ︙ | |||
272 273 274 275 276 277 278 279 280 281 282 283 284 285 | } -returnCodes error -result {user "noonewiththisname" doesn't exist} test filesystem-1.30.1 {normalisation of existing user} -body { catch {file normalize ~$::tcl_platform(user)} } -result {0} test filesystem-1.30.2 {normalisation of nonexistent user specified as user@domain} -body { file normalize ~nonexistentuser@nonexistentdomain } -returnCodes error -result {user "nonexistentuser@nonexistentdomain" doesn't exist} test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} { testsetplatform unix file normalize /foo/../bar } {/bar} test filesystem-1.32 {link normalisation: link near filesystem root} {testsetplatform} { testsetplatform unix file normalize /../bar | > > > > > > > > > > | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | } -returnCodes error -result {user "noonewiththisname" doesn't exist} test filesystem-1.30.1 {normalisation of existing user} -body { catch {file normalize ~$::tcl_platform(user)} } -result {0} test filesystem-1.30.2 {normalisation of nonexistent user specified as user@domain} -body { file normalize ~nonexistentuser@nonexistentdomain } -returnCodes error -result {user "nonexistentuser@nonexistentdomain" doesn't exist} test filesystem-1.30.3 {file normalization should distinguish between ~ and ~user} -setup { set oldhome $::env(HOME) set olduserhome [file normalize ~$::tcl_platform(user)] set ::env(HOME) [file join $oldhome temp] } -cleanup { set env(HOME) $oldhome } -body { list [string equal [file normalize ~] $::env(HOME)] \ [string equal $olduserhome [file normalize ~$::tcl_platform(user)]] } -result {1 1} test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} { testsetplatform unix file normalize /foo/../bar } {/bar} test filesystem-1.32 {link normalisation: link near filesystem root} {testsetplatform} { testsetplatform unix file normalize /../bar |
︙ | ︙ |
Changes to win/tclWinFile.c.
︙ | ︙ | |||
1453 1454 1455 1456 1457 1458 1459 | Tcl_DStringInit(bufferPtr); wDomain = NULL; domain = Tcl_UtfFindFirst(name, '@'); if (domain == NULL) { const char *ptr; | | | > > > > > > > > > > | | > > > < > > > | < | < | > > > > > | < | > | > > > | 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | Tcl_DStringInit(bufferPtr); wDomain = NULL; domain = Tcl_UtfFindFirst(name, '@'); if (domain == NULL) { const char *ptr; /* * Treat the current user as a special case because the general case * below does not properly retrieve the path. The NetUserGetInfo * call returns an empty path and the code defaults to the user's * name in the profiles directory. On modern Windows systems, this * is generally wrong as when the account is a Microsoft account, * for example [email protected], the directory name is * abcde and not abcdefghi. * * Note we could have just used env(USERPROFILE) here but * the intent is to retrieve (as on Unix) the system's view * of the home irrespective of environment settings of HOME * and USERPROFILE. * * Fixing this for the general user needs more investigating but * at least for the current user we can use a direct call. */ ptr = TclpGetUserName(&ds); if (ptr != NULL && strcasecmp(name, ptr) == 0) { HANDLE hProcess; WCHAR buf[MAX_PATH]; DWORD nChars = sizeof(buf) / sizeof(buf[0]); /* Sadly GetCurrentProcessToken not in Win 7 so slightly longer */ hProcess = GetCurrentProcess(); /* Need not be closed */ if (hProcess) { HANDLE hToken; if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) { if (GetUserProfileDirectoryW(hToken, buf, &nChars)) { Tcl_WinTCharToUtf((TCHAR *)buf, (nChars-1)*sizeof(WCHAR), bufferPtr); result = Tcl_DStringValue(bufferPtr); rc = 1; } CloseHandle(hToken); } } } Tcl_DStringFree(&ds); } else { Tcl_DStringInit(&ds); wName = Tcl_UtfToWCharDString(domain + 1, TCL_INDEX_NONE, &ds); rc = NetGetDCName(NULL, wName, (LPBYTE *) &wDomain); Tcl_DStringFree(&ds); |
︙ | ︙ | |||
1538 1539 1540 1541 1542 1543 1544 | } NetApiBufferFree((void *) uiPtr); } Tcl_DStringFree(&ds); } if (wDomain != NULL) { NetApiBufferFree((void *) wDomain); | < < < < < < < < < < < < < < < < < < < < < < < < | 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 | } NetApiBufferFree((void *) uiPtr); } Tcl_DStringFree(&ds); } if (wDomain != NULL) { NetApiBufferFree((void *) wDomain); } return result; } /* *--------------------------------------------------------------------------- |
︙ | ︙ |