MantisBT - CMake
View Issue Details
0015892CMakeCMakepublic2015-12-22 05:512016-05-02 08:30
Jan van Dorsten 
 
highmajoralways
closedfixed 
DellWindows10
CMake 3.4 
CMake 3.5CMake 3.5 
0015892: cmSystemTools::GetShortPath works not correct
The method "GetShortPath" does not work as expected. The error codes from the MSDN for the function "GetShortPathName" are not interpreted correctly.
No tags attached.
diff GetShortPath.diff (2,597) 2015-12-22 05:51
https://public.kitware.com/Bug/file/5596/GetShortPath.diff
Issue History
2015-12-22 05:51Jan van DorstenNew Issue
2015-12-22 05:51Jan van DorstenFile Added: GetShortPath.diff
2015-12-22 13:11Bill HoffmanNote Added: 0040020
2015-12-23 04:58Jan van DorstenNote Added: 0040021
2016-01-08 15:08Brad KingNote Added: 0040164
2016-01-11 11:21Brad KingNote Added: 0040188
2016-01-11 11:21Brad KingStatusnew => resolved
2016-01-11 11:21Brad KingResolutionopen => fixed
2016-01-11 11:21Brad KingFixed in Version => CMake 3.5
2016-01-11 11:21Brad KingTarget Version => CMake 3.5
2016-05-02 08:30Robert MaynardNote Added: 0040999
2016-05-02 08:30Robert MaynardStatusresolved => closed

Notes
(0040020)
Bill Hoffman   
2015-12-22 13:11   
Can you give an example where it fails to work correctly?
(0040021)
Jan van Dorsten   
2015-12-23 04:58   
I want to execute the program 7z. The program is installed at the location "D:\Program Files (x86)\7-Zip".

The WinAPI function "GetShortPathName" returns the size of the "shortPathBuffer" and that means the buffer is too small to store the short path of the executable.
So the buffer must be enlarged.

MSDN GetShortPathName: https://msdn.microsoft.com/de-de/library/windows/desktop/aa364989%28v=vs.85%29.aspx [^]

Function: DWORD WINAPI GetShortPathName(
                           _In_ LPCTSTR lpszLongPath,
                           _Out_ LPTSTR lpszShortPath,
                           _In_ DWORD cchBuffer
                           );

Quote: "Return value

If the function succeeds, the return value is the length, in TCHARs, of the string that is copied to lpszShortPath, not including the terminating null character.

If the lpszShortPath buffer is too small to contain the path, the return value is the size of the buffer, in TCHARs, that is required to hold the path and the terminating null character.

If the function fails for any other reason, the return value is zero. To get extended error information, call GetLastError."

Important is the second section: "If the lpszShortPath buffer is too small..."


In my case the value of "ret" is 32 and the "wtempPath.size()" is 31.
So the greater than comparison match and the function returns false.
(0040164)
Brad King   
2016-01-08 15:08   
Re 0015892:0040021: Thanks. These changes are in KWSys so I'll integrate them upstream there first. I split out the tempPath buffer change into its own commit. See here:

 http://review.source.kitware.com/20639 [^]

For the main logic change I don't see how this line works:

> + while(ret == buffer.size());

If the buffer is not large enough originally then the return value may be greater than its size, and the loop will not continue to try again.

Anyway, I made an alternative change. See here:

 http://review.source.kitware.com/20640 [^]

Please try copying these two changes over to your CMake source to check that it resolves the problem for you.

Unfortunately GetShortPath cannot be easily tested because GetShortPathName works on paths that must exist, and the right answer depends on filesystem content we do not control.
(0040188)
Brad King   
2016-01-11 11:21   
Re 0015892:0040164: The change has been merged to upstream KWSys. Here is a change integrating the updated KWSys into CMake:

 KWSys 2016-01-11 (e8bf616e)
 https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8e7356a2 [^]
(0040999)
Robert Maynard   
2016-05-02 08:30   
Closing resolved issues that have not been updated in more than 4 months.