> On 19 Feb 2023, at 21:23, Maxim Dounin <mdou...@mdounin.ru> wrote: > > Hello! > > On Fri, Feb 17, 2023 at 07:04:04PM +0400, Sergey Kandaurov wrote: > >>> On 13 Jan 2023, at 01:35, Maxim Dounin <mdou...@mdounin.ru> wrote: >>> >>> # HG changeset patch >>> # User Maxim Dounin <mdou...@mdounin.ru> >>> # Date 1673548916 -10800 >>> # Thu Jan 12 21:41:56 2023 +0300 >>> # Node ID 7cf820c46860796cff91f53a5d2db669bb5b5a6c >>> # Parent d05c0adf5890aecc68ce8906ef19ca07502ed071 >>> Win32: non-ASCII directory names support in ngx_getcwd(). >>> >>> This makes it possible to start nginx without a prefix explicitly set >>> in a directory with non-ASCII characters in it. >>> >>> diff -r d05c0adf5890 -r 7cf820c46860 src/os/win32/ngx_files.c >>> --- a/src/os/win32/ngx_files.c Thu Jan 12 21:41:39 2023 +0300 >>> +++ b/src/os/win32/ngx_files.c Thu Jan 12 21:41:56 2023 +0300 >>> @@ -428,6 +428,30 @@ ngx_realpath(u_char *path, u_char *resol >>> } >>> >>> >>> +size_t >>> +ngx_getcwd(u_char *buf, size_t size) >>> +{ >>> + u_char *p; >>> + size_t n; >>> + u_short utf16[NGX_MAX_PATH]; >>> + >>> + n = GetCurrentDirectoryW(NGX_MAX_PATH, utf16); >>> + >>> + if (n == 0) { >>> + return 0; >>> + } > > Re-reading the documentation, I tend to think this might worth an > additional test for "(n > NGX_MAX_PATH)" > (https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcurrentdirectory): > > : If the function succeeds, the return value specifies the number > : of characters that are written to the buffer, not including the > : terminating null character. > > : If the function fails, the return value is zero. To get extended > : error information, call GetLastError. > > : If the buffer that is pointed to by lpBuffer is not large > : enough, the return value specifies the required size of the > : buffer, in characters, including the null-terminating character. > > That is, there will be no explicit error (n == 0) if the buffer > will happen to be insufficient. On the other hand, this probably > can happen with long paths enabled (see > https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry), > > so it might be a good idea to add an explicit handling while here. >
Yes, I looked through GetCurrentDirectory return values, but didn't pay an attention on long paths support. Considering them, it may have sense to add such checks. >>> + >>> + p = ngx_utf16_to_utf8(buf, utf16, &size, NULL); >>> + >> >> No error check may result in double-free, first freed >> after (re-)allocation on NGX_EILSEQ, then as below. > > Free on NGX_EILSEQ after reallocation only frees the memory > allocated by the ngx_utf16_to_utf8() itself. The incorrect free() > was before reallocation, and is now fixed. > > Since on errors ngx_utf16_to_utf8() returns NULL, it is matched by > the "if (p != buf)" test, and processed identically to > reallocations. The only questionable part is ngx_free(NULL), > though as per C standard (starting at least with C89; and also > win32 documentation) this is guaranteed to be a nop. > >>> + if (p != buf) { >>> + ngx_free(p); >>> + return 0; >> >> Why return an error if (re-)allocation happened? >> Sizes (calculated in 1-byte units) above NGX_MAX_PATH >> seem perfectly valid with multibyte UTF-8. > > The ngx_getcwd() interface does not provide a way to return a new > pointer. Rather, it is strictly limited to the buffer provided by > the caller, and can only return an error if the buffer is not > large enough. Sure, missed that point. > > One possible improvement here is to explicitly set the errno to a > reasonable value if this happens. This would require an explicit > handling of other errors though. > > Combined with the above: > > diff -r 6705dd675ace src/os/win32/ngx_files.c > --- a/src/os/win32/ngx_files.c Sat Feb 18 16:01:20 2023 +0300 > +++ b/src/os/win32/ngx_files.c Sun Feb 19 03:22:48 2023 +0300 > @@ -442,10 +442,20 @@ ngx_getcwd(u_char *buf, size_t size) > return 0; > } > > + if (n > NGX_MAX_PATH) { > + ngx_set_errno(ERROR_INSUFFICIENT_BUFFER); > + return 0; > + } > + > p = ngx_utf16_to_utf8(buf, utf16, &size, NULL); > > + if (p == NULL) { > + return 0; > + } > + > if (p != buf) { > ngx_free(p); > + ngx_set_errno(ERROR_INSUFFICIENT_BUFFER); > return 0; > } > > > [...] > Thanks for the lengthy explanation. The proposed addition looks good to me. -- Sergey Kandaurov _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel