Skip to content

Conversation

@MarvelMathesh
Copy link

Fixes: #8361

This PR extends Windows long path support (paths > 260 characters) to file operations using CreateFile API, particularly for getting and setting file timestamps in the curl command-line tool.

Implement curlx_win32_fix_long_path() to normalize, handle excessive/\?\ long Windows paths and return a heap-allocated TCHAR* (UTF-16 or multibyte as appropriate). Replace direct curlx_convert_UTF8_to_tchar() calls in tool_filetime with the new helper so filetime operations work with long paths.

@jay
Copy link
Member

jay commented Oct 30, 2025

Please fix for failing CI due to trailing whitespace in the blank lines.

Also, I'm pretty sure curlx functions are not supposed to return memory-tracked memory pointers unless the comments here are wrong. So what that means is you don't return strdup(xyz) instead you have to return (strdup)(xyz) so that curlx_unicodefree can properly free it (that function just calls (free) like (free)(path)). If anyone else wants to weigh in on this , I'm not positive.

Comment on lines 333 to 354
#ifdef _UNICODE
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
if(path_w) {
if(fix_excessive_path(path_w, &fixed))
target = fixed;
else
target = path_w;

if(target) {
result = _wcsdup(target);
(free)(fixed);
}
curlx_unicodefree(path_w);
}
#else
if(fix_excessive_path(path, &fixed))
target = fixed;
else
target = path;

if(target)
result = strdup(target);

(free)(fixed);
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On further inspection it seems you may be able to eliminate some dup. The only thing that would need strdup is the passed in path. The other pointers already point to memory that is created outside the memory tracker (in curlx_ prefixed functions or helper functions)

target = NULL;
#ifdef _UNICODE
  wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
  if(path_w) {
    if(fix_excessive_path(path_w, &fixed)) {
      target = fixed;
      (free)(path_w);
    }
    else
      target = path_w;
  }
#else
  if(fix_excessive_path(path, &fixed))
    target = fixed;
  else
    target = (strdup)(path);
#endif

return target;

Copy link
Member

@jay jay Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could consolidate it even further by returning directly return fixed etc, that would get rid of the two lines nm I see a flaw in that because you'd still have to return NULL in one case

@vszakats
Copy link
Member

There is a 3rd CreateFile() call in lib/vtls/schannel_verify.c. Would it be possible apply this change there also?

else
target = path_w;

result = (_wcsdup)(target);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result = (_wcsdup)(target);
result = _wcsdup(target);

curl doesn't override this function, making it safe to call as-is.

return NULL;

#ifdef _UNICODE
wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI failing due to this line. Fix is to create a block, or move the declaration to the top of the function.

C:/projects/curl/lib/curlx/fopen.c(334,12): error : mixing declarations and code is incompatible with standards before C99 [-Werror,-Wdeclaration-after-statement] [C:\projects\curl_bld\lib\libcurl_object.vcxproj]

@vszakats
Copy link
Member

Implemented slightly differently, also for all CreateFile calls in curl, via PR ##20040.

Thanks for the PR and for raising the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

[Windows] Long-filename problem

3 participants