mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-03 07:25:03 +00:00 
			
		
		
		
	REF: https://bugzilla.tianocore.org/show_bug.cgi?id=705 As mentioned in the above Bugzilla link by Steven, within the function PathCleanUpDirectories(), when executing command: "cd ." under Shell, the input parameter 'Path' string will have string length less than 2. Hence, it is possible for the below statement: "if (StrCmp (Path + StrLen (Path) - 2, L"\\.") == 0) {" to read contents before the string boundary. This commit adds additional checks to avoid this. Cc: Steven Shi <steven.shi@intel.com> Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
		
			
				
	
	
		
			119 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Defines file-path manipulation functions.
 | 
						|
 | 
						|
  Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>
 | 
						|
  This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php.
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
**/
 | 
						|
#include  <Library/BaseMemoryLib.h>
 | 
						|
#include  <Library/BaseLib.h>
 | 
						|
 | 
						|
/**
 | 
						|
  Removes the last directory or file entry in a path. For a path which is
 | 
						|
  like L"fs0:startup.nsh", it's converted to L"fs0:".
 | 
						|
 | 
						|
  @param[in,out] Path     A pointer to the path to modify.
 | 
						|
 | 
						|
  @retval FALSE     Nothing was found to remove.
 | 
						|
  @retval TRUE      A directory or file was removed.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
PathRemoveLastItem(
 | 
						|
  IN OUT CHAR16 *Path
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16        *Walker;
 | 
						|
  CHAR16        *LastSlash;
 | 
						|
  //
 | 
						|
  // get directory name from path... ('chop' off extra)
 | 
						|
  //
 | 
						|
  for ( Walker = Path, LastSlash = NULL
 | 
						|
      ; Walker != NULL && *Walker != CHAR_NULL
 | 
						|
      ; Walker++
 | 
						|
     ){
 | 
						|
    if (*Walker == L'\\' && *(Walker + 1) != CHAR_NULL) {
 | 
						|
      LastSlash = Walker+1;
 | 
						|
    } else if (*Walker == L':' && *(Walker + 1) != L'\\' && *(Walker + 1) != CHAR_NULL) {
 | 
						|
      LastSlash = Walker+1;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (LastSlash != NULL) {
 | 
						|
    *LastSlash = CHAR_NULL;
 | 
						|
    return (TRUE);
 | 
						|
  }
 | 
						|
  return (FALSE);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Function to clean up paths.
 | 
						|
 | 
						|
  - Single periods in the path are removed.
 | 
						|
  - Double periods in the path are removed along with a single parent directory.
 | 
						|
  - Forward slashes L'/' are converted to backward slashes L'\'.
 | 
						|
 | 
						|
  This will be done inline and the existing buffer may be larger than required
 | 
						|
  upon completion.
 | 
						|
 | 
						|
  @param[in] Path       The pointer to the string containing the path.
 | 
						|
 | 
						|
  @return       Returns Path, otherwise returns NULL to indicate that an error has occured.
 | 
						|
**/
 | 
						|
CHAR16*
 | 
						|
EFIAPI
 | 
						|
PathCleanUpDirectories(
 | 
						|
  IN CHAR16 *Path
 | 
						|
)
 | 
						|
{
 | 
						|
  CHAR16  *TempString;
 | 
						|
 | 
						|
  if (Path == NULL) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Replace the '/' with '\'
 | 
						|
  //
 | 
						|
  for (TempString = Path; *TempString != CHAR_NULL; TempString++) {
 | 
						|
    if (*TempString == L'/') {
 | 
						|
      *TempString = L'\\';
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Remove all the "\.". E.g.: fs0:\abc\.\def\.
 | 
						|
  //
 | 
						|
  while ((TempString = StrStr (Path, L"\\.\\")) != NULL) {
 | 
						|
    CopyMem (TempString, TempString + 2, StrSize (TempString + 2));
 | 
						|
  }
 | 
						|
  if ((StrLen (Path) >= 2) && (StrCmp (Path + StrLen (Path) - 2, L"\\.") == 0)) {
 | 
						|
    Path[StrLen (Path) - 1] = CHAR_NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Remove all the "\..". E.g.: fs0:\abc\..\def\..
 | 
						|
  //
 | 
						|
  while (((TempString = StrStr(Path, L"\\..")) != NULL) &&
 | 
						|
         ((*(TempString + 3) == L'\\') || (*(TempString + 3) == CHAR_NULL))
 | 
						|
        ) {
 | 
						|
    *(TempString + 1) = CHAR_NULL;
 | 
						|
    PathRemoveLastItem(Path);
 | 
						|
    CopyMem (Path + StrLen (Path), TempString + 3, StrSize (TempString + 3));
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Replace the "\\" with "\"
 | 
						|
  //
 | 
						|
  while ((TempString = StrStr (Path, L"\\\\")) != NULL) {
 | 
						|
    CopyMem (TempString, TempString + 1, StrSize (TempString + 1));
 | 
						|
  }
 | 
						|
 | 
						|
  return Path;
 | 
						|
}
 | 
						|
 |