mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Improve fs::PathStartsWith to handle empty strings (#14877)
`""` does not refer to a proper path, and `fs::PathStartsWith(path, "")` should just return `false`. This is also the case in libraries in other languages where I looked, seems to be common. The new behavior: * check early, if `prefix` is empty - return if path is empty or not, * no special processing for when `path` is empty, the function meets characters in `prefix` and returns false anyway.
This commit is contained in:
		@@ -697,32 +697,43 @@ bool MoveDir(const std::string &source, const std::string &target)
 | 
			
		||||
 | 
			
		||||
bool PathStartsWith(const std::string &path, const std::string &prefix)
 | 
			
		||||
{
 | 
			
		||||
	if (prefix.empty())
 | 
			
		||||
		return path.empty();
 | 
			
		||||
	size_t pathsize = path.size();
 | 
			
		||||
	size_t pathpos = 0;
 | 
			
		||||
	size_t prefixsize = prefix.size();
 | 
			
		||||
	size_t prefixpos = 0;
 | 
			
		||||
	for(;;){
 | 
			
		||||
		// Test if current characters at path and prefix are delimiter OR EOS
 | 
			
		||||
		bool delim1 = pathpos == pathsize
 | 
			
		||||
			|| IsDirDelimiter(path[pathpos]);
 | 
			
		||||
		bool delim2 = prefixpos == prefixsize
 | 
			
		||||
			|| IsDirDelimiter(prefix[prefixpos]);
 | 
			
		||||
 | 
			
		||||
		// Return false if it's delimiter/EOS in one path but not in the other
 | 
			
		||||
		if(delim1 != delim2)
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		if(delim1){
 | 
			
		||||
			// Skip consequent delimiters in path, in prefix
 | 
			
		||||
			while(pathpos < pathsize &&
 | 
			
		||||
					IsDirDelimiter(path[pathpos]))
 | 
			
		||||
				++pathpos;
 | 
			
		||||
			while(prefixpos < prefixsize &&
 | 
			
		||||
					IsDirDelimiter(prefix[prefixpos]))
 | 
			
		||||
				++prefixpos;
 | 
			
		||||
			// Return true if prefix has ended (at delimiter/EOS)
 | 
			
		||||
			if(prefixpos == prefixsize)
 | 
			
		||||
				return true;
 | 
			
		||||
			// Return false if path has ended (at delimiter/EOS)
 | 
			
		||||
            // while prefix did not.
 | 
			
		||||
			if(pathpos == pathsize)
 | 
			
		||||
				return false;
 | 
			
		||||
		}
 | 
			
		||||
		else{
 | 
			
		||||
			// Skip pairwise-equal characters in path and prefix until
 | 
			
		||||
			// delimiter/EOS in path or prefix.
 | 
			
		||||
			// Return false if differing characters are met.
 | 
			
		||||
			size_t len = 0;
 | 
			
		||||
			do{
 | 
			
		||||
				char pathchar = path[pathpos+len];
 | 
			
		||||
 
 | 
			
		||||
@@ -113,6 +113,7 @@ void TestFileSys::testPathStartsWith()
 | 
			
		||||
	};
 | 
			
		||||
	/*
 | 
			
		||||
		expected fs::PathStartsWith results
 | 
			
		||||
		(row for every path, column for every prefix)
 | 
			
		||||
		0 = returns false
 | 
			
		||||
		1 = returns true
 | 
			
		||||
		2 = returns false on windows, true elsewhere
 | 
			
		||||
@@ -122,17 +123,17 @@ void TestFileSys::testPathStartsWith()
 | 
			
		||||
	*/
 | 
			
		||||
	int expected_results[numpaths][numpaths] = {
 | 
			
		||||
		{1,2,0,0,0,0,0,0,0,0,0,0},
 | 
			
		||||
		{1,1,0,0,0,0,0,0,0,0,0,0},
 | 
			
		||||
		{1,1,1,0,0,0,0,0,0,0,0,0},
 | 
			
		||||
		{1,1,1,1,0,0,0,0,0,0,0,0},
 | 
			
		||||
		{1,1,0,0,1,0,0,0,0,0,0,0},
 | 
			
		||||
		{1,1,0,0,0,1,0,0,1,1,0,0},
 | 
			
		||||
		{1,1,0,0,0,0,1,4,1,0,0,0},
 | 
			
		||||
		{1,1,0,0,0,0,4,1,4,0,0,0},
 | 
			
		||||
		{1,1,0,0,0,0,0,0,1,0,0,0},
 | 
			
		||||
		{1,1,0,0,0,0,0,0,1,1,0,0},
 | 
			
		||||
		{1,1,0,0,0,0,0,0,0,0,1,0},
 | 
			
		||||
		{1,1,0,0,0,0,0,0,0,0,0,1},
 | 
			
		||||
		{0,1,0,0,0,0,0,0,0,0,0,0},
 | 
			
		||||
		{0,1,1,0,0,0,0,0,0,0,0,0},
 | 
			
		||||
		{0,1,1,1,0,0,0,0,0,0,0,0},
 | 
			
		||||
		{0,1,0,0,1,0,0,0,0,0,0,0},
 | 
			
		||||
		{0,1,0,0,0,1,0,0,1,1,0,0},
 | 
			
		||||
		{0,1,0,0,0,0,1,4,1,0,0,0},
 | 
			
		||||
		{0,1,0,0,0,0,4,1,4,0,0,0},
 | 
			
		||||
		{0,1,0,0,0,0,0,0,1,0,0,0},
 | 
			
		||||
		{0,1,0,0,0,0,0,0,1,1,0,0},
 | 
			
		||||
		{0,1,0,0,0,0,0,0,0,0,1,0},
 | 
			
		||||
		{0,1,0,0,0,0,0,0,0,0,0,1},
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < numpaths; i++)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user