allow opening a character device prefixed with invalid drive letter (e.g. "@:NUL") but not with invalid path

This commit is contained in:
Kenneth J Davis 2021-08-19 00:00:29 -04:00
parent c69638def9
commit 6ada304ec2
2 changed files with 74 additions and 13 deletions

View File

@ -304,7 +304,63 @@ COUNT truename(const char FAR * src, char * dest, COUNT mode)
cdsEntry = get_cds(result);
if (cdsEntry == NULL)
{
return DE_PATHNOTFND;
/* If opening a character device, DOS allows device name
to be prefixed by [invalid] drive letter and/or optionally
\DEV\ directory prefix, however, any other directory
including root (\) is an invalid path if drive is not
valid and returns such.
Whereas truename always fails for invalid drive.
*/
if (dhp && (mode & CDS_MODE_CHECK_DEV_PATH) && (result >= lastdrive))
{
/* Note: check for (result >= lastdrive) means invalid drive
was provided as otherwise we would have used default_drive
so we know src in the form of X:?
fail if anything other than no path or path is \DEV\
*/
char drivesep[] = "\\/";
const char FAR *s = src+2;
const char *d = strchr(drivesep, *s); /* ?path starts with \ or / */
/* could be 1 letter devicename, don't go scanning random memory */
if (*(src+3) != '\0')
{
s = fstrchr(src+3, '\\'); /* ?is there \ or / other than immediately after drive: */
if (s == NULL) s = fstrchr(src+3, '/');
}
else
{
s = NULL;
}
if (d == NULL)
{
/* either X:devicename or X:path\devicename */
if (s != NULL) goto invalid_path;
}
else
{
/* either X:\devicename or X:\path\devicename
only X:\DEV\devicename is valid path
*/
if (s == NULL) goto invalid_path;
if (s != src+6) goto invalid_path;
if (fmemcmp(src+3, "DEV", 3) != 0) goto invalid_path;
s = fstrchr(src+7, '\\');
if (s == NULL) s = fstrchr(src+7, '/');
if (s != NULL) goto invalid_path;
}
/* use CDS of current drive (MS-DOS may return drive P: for invalid drive.) */
result = default_drive;
cdsEntry = get_cds(result);
if (cdsEntry == NULL) goto invalid_path;
}
else
{
invalid_path:
return DE_PATHNOTFND;
}
}
fmemcpy(&TempCDS, cdsEntry, sizeof(TempCDS));

View File

@ -81,29 +81,34 @@ int do_tests_on(const char *device_name)
const char current_drive = (char)('A'+_getdrive()-1);
sprintf(buffer, "%s", device_name);
if (!test_device('@', buffer,0)) status = FAILURE;
if (!test_device(current_drive, buffer,0)) status = FAILURE;
if (!test_device('@', buffer,0)) status = FAILURE; /* special, should succeed */
if (!test_device(current_drive, buffer,0)) status = FAILURE; /* valid directory, should succeed */
/* DIREXIST should exist in the current directory */
sprintf(buffer, "DIREXIST\\%s", device_name);
if (!test_device('@', buffer,1)) status = FAILURE; /* drive does not exist, should fail */
if (!test_device(current_drive, buffer,0)) status = FAILURE; /* valid drive, should succeed */
if (!test_device('@', buffer,1)) status = FAILURE; /* directory does not exist, should fail */
if (!test_device(current_drive, buffer,0)) status = FAILURE; /* valid directory, should succeed */
sprintf(buffer, "BAD_PATH\\%s", device_name);
if (!test_device('@', buffer,1)) status = FAILURE;
if (!test_device(current_drive, buffer,1)) status = FAILURE;
if (!test_device('@', buffer,1)) status = FAILURE; /* directory does not exist, should fail */
if (!test_device(current_drive, buffer,1)) status = FAILURE; /* directory does not exist, should fail */
/* assumes DEV directory does not exist in current directory */
sprintf(buffer, "DEV\\%s", device_name);
if (!test_device('@', buffer,1)) status = FAILURE; /* directory does not exist, should fail */
if (!test_device(current_drive, buffer,1)) status = FAILURE; /* directory does not exist, should fail */
sprintf(buffer, "\\%s", device_name);
if (!test_device('@', buffer,1)) status = FAILURE; /* drive does not exist, should fail */
if (!test_device(current_drive, buffer,0)) status = FAILURE; /* valid drive, should succeed */
if (!test_device('@', buffer,1)) status = FAILURE; /* directory does not exist, should fail */
if (!test_device(current_drive, buffer,0)) status = FAILURE; /* valid directory, should succeed */
sprintf(buffer, "\\BAD_PATH\\%s", device_name);
if (!test_device('@', buffer,1)) status = FAILURE;
if (!test_device(current_drive, buffer,1)) status = FAILURE;
if (!test_device('@', buffer,1)) status = FAILURE; /* directory does not exist, should fail */
if (!test_device(current_drive, buffer,1)) status = FAILURE; /* directory does not exist, should fail */
sprintf(buffer, "\\DEV\\%s", device_name);
if (!test_device('@', buffer,0)) status = FAILURE;
if (!test_device(current_drive, buffer,0)) status = FAILURE;
if (!test_device('@', buffer,0)) status = FAILURE; /* special, should succeed */
if (!test_device(current_drive, buffer,0)) status = FAILURE; /* special, should succeed */
return status;
}