@@ -491,62 +491,39 @@ dumpSearchInfo(SearchInfo *search)
491491
492492
493493int
494- findArgumentLength (const wchar_t * buffer , int bufferLength )
494+ findArgv0Length (const wchar_t * buffer , int bufferLength )
495495{
496- if (bufferLength < 0 ) {
497- bufferLength = (int )wcsnlen_s (buffer , MAXLEN );
498- }
499- if (bufferLength == 0 ) {
500- return 0 ;
501- }
502- const wchar_t * end ;
503- int i ;
504-
505- if (buffer [0 ] != L'"' ) {
506- end = wcschr (buffer , L' ' );
507- if (!end ) {
508- return bufferLength ;
509- }
510- i = (int )(end - buffer );
511- return i < bufferLength ? i : bufferLength ;
512- }
513-
514- i = 0 ;
515- while (i < bufferLength ) {
516- end = wcschr (& buffer [i + 1 ], L'"' );
517- if (!end ) {
518- return bufferLength ;
519- }
520-
521- i = (int )(end - buffer );
522- if (i >= bufferLength ) {
523- return bufferLength ;
524- }
525-
526- int j = i ;
527- while (j > 1 && buffer [-- j ] == L'\\' ) {
528- if (j > 0 && buffer [-- j ] == L'\\' ) {
529- // Even number, so back up and keep counting
530- } else {
531- // Odd number, so it's escaped and we want to keep searching
532- continue ;
496+ // Note: this implements semantics that are only valid for argv0.
497+ // Specifically, there is no escaping of quotes, and quotes within
498+ // the argument have no effect. A quoted argv0 must start and end
499+ // with a double quote character; otherwise, it ends at the first
500+ // ' ' or '\t'.
501+ int quoted = buffer [0 ] == L'"' ;
502+ for (int i = 1 ; bufferLength < 0 || i < bufferLength ; ++ i ) {
503+ switch (buffer [i ]) {
504+ case L'\0' :
505+ return i ;
506+ case L' ' :
507+ case L'\t' :
508+ if (!quoted ) {
509+ return i ;
533510 }
534- }
535-
536- // Non-escaped quote with space after it - end of the argument!
537- if (i + 1 >= bufferLength || isspace (buffer [i + 1 ])) {
538- return i + 1 ;
511+ break ;
512+ case L'"' :
513+ if (quoted ) {
514+ return i + 1 ;
515+ }
516+ break ;
539517 }
540518 }
541-
542519 return bufferLength ;
543520}
544521
545522
546523const wchar_t *
547- findArgumentEnd (const wchar_t * buffer , int bufferLength )
524+ findArgv0End (const wchar_t * buffer , int bufferLength )
548525{
549- return & buffer [findArgumentLength (buffer , bufferLength )];
526+ return & buffer [findArgv0Length (buffer , bufferLength )];
550527}
551528
552529
@@ -562,11 +539,16 @@ parseCommandLine(SearchInfo *search)
562539 return RC_NO_COMMANDLINE ;
563540 }
564541
565- const wchar_t * tail = findArgumentEnd (search -> originalCmdLine , -1 );
566- const wchar_t * end = tail ;
567- search -> restOfCmdLine = tail ;
542+ const wchar_t * argv0End = findArgv0End (search -> originalCmdLine , -1 );
543+ const wchar_t * tail = argv0End ; // will be start of the executable name
544+ const wchar_t * end = argv0End ; // will be end of the executable name
545+ search -> restOfCmdLine = argv0End ; // will be first space after argv0
568546 while (-- tail != search -> originalCmdLine ) {
569- if (* tail == L'.' && end == search -> restOfCmdLine ) {
547+ if (* tail == L'"' && end == argv0End ) {
548+ // Move the "end" up to the quote, so we also allow moving for
549+ // a period later on.
550+ end = argv0End = tail ;
551+ } else if (* tail == L'.' && end == argv0End ) {
570552 end = tail ;
571553 } else if (* tail == L'\\' || * tail == L'/' ) {
572554 ++ tail ;
0 commit comments