mirror of
https://github.com/minetest/minetest.git
synced 2024-11-30 03:23:45 +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:
parent
5b19d315b3
commit
cfa9c83d33
@ -697,32 +697,43 @@ bool MoveDir(const std::string &source, const std::string &target)
|
|||||||
|
|
||||||
bool PathStartsWith(const std::string &path, const std::string &prefix)
|
bool PathStartsWith(const std::string &path, const std::string &prefix)
|
||||||
{
|
{
|
||||||
|
if (prefix.empty())
|
||||||
|
return path.empty();
|
||||||
size_t pathsize = path.size();
|
size_t pathsize = path.size();
|
||||||
size_t pathpos = 0;
|
size_t pathpos = 0;
|
||||||
size_t prefixsize = prefix.size();
|
size_t prefixsize = prefix.size();
|
||||||
size_t prefixpos = 0;
|
size_t prefixpos = 0;
|
||||||
for(;;){
|
for(;;){
|
||||||
|
// Test if current characters at path and prefix are delimiter OR EOS
|
||||||
bool delim1 = pathpos == pathsize
|
bool delim1 = pathpos == pathsize
|
||||||
|| IsDirDelimiter(path[pathpos]);
|
|| IsDirDelimiter(path[pathpos]);
|
||||||
bool delim2 = prefixpos == prefixsize
|
bool delim2 = prefixpos == prefixsize
|
||||||
|| IsDirDelimiter(prefix[prefixpos]);
|
|| IsDirDelimiter(prefix[prefixpos]);
|
||||||
|
|
||||||
|
// Return false if it's delimiter/EOS in one path but not in the other
|
||||||
if(delim1 != delim2)
|
if(delim1 != delim2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(delim1){
|
if(delim1){
|
||||||
|
// Skip consequent delimiters in path, in prefix
|
||||||
while(pathpos < pathsize &&
|
while(pathpos < pathsize &&
|
||||||
IsDirDelimiter(path[pathpos]))
|
IsDirDelimiter(path[pathpos]))
|
||||||
++pathpos;
|
++pathpos;
|
||||||
while(prefixpos < prefixsize &&
|
while(prefixpos < prefixsize &&
|
||||||
IsDirDelimiter(prefix[prefixpos]))
|
IsDirDelimiter(prefix[prefixpos]))
|
||||||
++prefixpos;
|
++prefixpos;
|
||||||
|
// Return true if prefix has ended (at delimiter/EOS)
|
||||||
if(prefixpos == prefixsize)
|
if(prefixpos == prefixsize)
|
||||||
return true;
|
return true;
|
||||||
|
// Return false if path has ended (at delimiter/EOS)
|
||||||
|
// while prefix did not.
|
||||||
if(pathpos == pathsize)
|
if(pathpos == pathsize)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else{
|
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;
|
size_t len = 0;
|
||||||
do{
|
do{
|
||||||
char pathchar = path[pathpos+len];
|
char pathchar = path[pathpos+len];
|
||||||
|
@ -113,6 +113,7 @@ void TestFileSys::testPathStartsWith()
|
|||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
expected fs::PathStartsWith results
|
expected fs::PathStartsWith results
|
||||||
|
(row for every path, column for every prefix)
|
||||||
0 = returns false
|
0 = returns false
|
||||||
1 = returns true
|
1 = returns true
|
||||||
2 = returns false on windows, true elsewhere
|
2 = returns false on windows, true elsewhere
|
||||||
@ -122,17 +123,17 @@ void TestFileSys::testPathStartsWith()
|
|||||||
*/
|
*/
|
||||||
int expected_results[numpaths][numpaths] = {
|
int expected_results[numpaths][numpaths] = {
|
||||||
{1,2,0,0,0,0,0,0,0,0,0,0},
|
{1,2,0,0,0,0,0,0,0,0,0,0},
|
||||||
{1,1,0,0,0,0,0,0,0,0,0,0},
|
{0,1,0,0,0,0,0,0,0,0,0,0},
|
||||||
{1,1,1,0,0,0,0,0,0,0,0,0},
|
{0,1,1,0,0,0,0,0,0,0,0,0},
|
||||||
{1,1,1,1,0,0,0,0,0,0,0,0},
|
{0,1,1,1,0,0,0,0,0,0,0,0},
|
||||||
{1,1,0,0,1,0,0,0,0,0,0,0},
|
{0,1,0,0,1,0,0,0,0,0,0,0},
|
||||||
{1,1,0,0,0,1,0,0,1,1,0,0},
|
{0,1,0,0,0,1,0,0,1,1,0,0},
|
||||||
{1,1,0,0,0,0,1,4,1,0,0,0},
|
{0,1,0,0,0,0,1,4,1,0,0,0},
|
||||||
{1,1,0,0,0,0,4,1,4,0,0,0},
|
{0,1,0,0,0,0,4,1,4,0,0,0},
|
||||||
{1,1,0,0,0,0,0,0,1,0,0,0},
|
{0,1,0,0,0,0,0,0,1,0,0,0},
|
||||||
{1,1,0,0,0,0,0,0,1,1,0,0},
|
{0,1,0,0,0,0,0,0,1,1,0,0},
|
||||||
{1,1,0,0,0,0,0,0,0,0,1,0},
|
{0,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,1},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < numpaths; i++)
|
for (int i = 0; i < numpaths; i++)
|
||||||
|
Loading…
Reference in New Issue
Block a user