Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1826 - emulator crash when too many versions of a file in a directory #512

Merged
merged 2 commits into from
Sep 17, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 29 additions & 23 deletions src/dsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static int get_old(char *dir, FileName *varray, char *afile, char *vfile);
static int get_oldest(char *dir, FileName *varray, char *afile, char *vfile);
static int get_new(char *dir, FileName *varray, char *afile, char *vfile);
static int get_old_new(char *dir, FileName *varray, char *afile, char *vfile);
static int get_version_array(char *dir, char *file, FileName *varray, CurrentVArray *cache);
static int get_version_array(char *dir, char *file, FileName varray[], CurrentVArray *cache);

#ifdef DOS
static void separate_drive(char *lfname, char *drive)
Expand Down Expand Up @@ -2938,15 +2938,15 @@ static int make_directory(char *dir)
/* */
/************************************************************************/

static int get_version_array(char *dir, char *file, FileName *varray, CurrentVArray *cache)
static int get_version_array(char *dir, char *file, FileName varray[], CurrentVArray *cache)
{
#ifdef DOS

/* DOS version-array builder */
char lcased_file[MAXPATHLEN];
char old_file[MAXPATHLEN];
char name[MAXNAMLEN];
char ver[VERSIONLEN];
FileName *svarray;
int varray_index = 0;
struct find_t dirp;
struct direct *dp;
int rval, drive = 0, isslash = 0;
Expand Down Expand Up @@ -2987,14 +2987,12 @@ static int get_version_array(char *dir, char *file, FileName *varray, CurrentVAr

make_old_version(old_file, lcased_file);

svarray = varray;

TIMEOUT(res = _dos_findfirst(old_file, _A_NORMAL | _A_SUBDIR, &dirp));
if (res == 0) {
strcpy(name, dirp.name);
strcpy(svarray->name, name);
svarray->version_no = 0;
svarray++;
strcpy(varray[varray_index].name, name);
varray[varray_index].version_no = 0;
varray_index++;
}

/*******************************/
Expand All @@ -3013,25 +3011,29 @@ static int get_version_array(char *dir, char *file, FileName *varray, CurrentVAr
separate_version(name, ver, 1);
DOWNCASE(name);

strcpy(svarray->name, dirp.name);
strcpy(varray[varray_index].name, dirp.name);
if (*ver == '\0') {
/* Versionless file */
svarray->version_no = 1;
varray[varray_index].version_no = 1;
} else {
/*
* separator_version guarantees ver is a numeric
* string.
*/
svarray->version_no = strtoul(ver, (char **)NULL, 10);
varray[varray_index].version_no = strtoul(ver, (char **)NULL, 10);
}
svarray++;
varray_index++;
if (varray_index >= VERSIONARRAYLENGTH) {
/* how does the specific error get signalled in the DOS case? */
return (0);
}
}

/*
* The last entry of varray is indicated by setting LASTVERSIONARRAY into
* version_no field.
*/
svarray->version_no = LASTVERSIONARRAY;
varray[varray_index].version_no = LASTVERSIONARRAY;

/*
* If more than one files have been stored in varray, we store the name
Expand All @@ -3040,7 +3042,7 @@ static int get_version_array(char *dir, char *file, FileName *varray, CurrentVAr
if (!NoFileP(varray)) {
strcpy(name, varray->name);
separate_version(name, ver, 1);
strcpy(svarray->name, name);
strcpy(varray[varray_index].name, name);
}

return (1);
Expand All @@ -3050,7 +3052,7 @@ static int get_version_array(char *dir, char *file, FileName *varray, CurrentVAr
char lcased_file[MAXNAMLEN];
char name[MAXNAMLEN];
char ver[VERSIONLEN];
FileName *svarray;
int varray_index = 0;
DIR *dirp;
struct dirent *dp;
int rval;
Expand Down Expand Up @@ -3095,7 +3097,7 @@ static int get_version_array(char *dir, char *file, FileName *varray, CurrentVAr
return (0);
}

for (S_TOUT(dp = readdir(dirp)), svarray = varray; dp != NULL || errno == EINTR;
for (S_TOUT(dp = readdir(dirp)); dp != NULL || errno == EINTR;
errno = 0, S_TOUT(dp = readdir(dirp)))
if (dp) {
strcpy(name, dp->d_name);
Expand All @@ -3105,25 +3107,29 @@ static int get_version_array(char *dir, char *file, FileName *varray, CurrentVAr
/*
* This file can be regarded as a same file in Lisp sense.
*/
strcpy(svarray->name, dp->d_name);
strcpy(varray[varray_index].name, dp->d_name);
if (*ver == '\0') {
/* Versionless file */
svarray->version_no = 0;
varray[varray_index].version_no = 0;
} else {
/*
* separator_version guarantees ver is a numeric
* string.
*/
svarray->version_no = strtoul(ver, (char **)NULL, 10);
varray[varray_index].version_no = strtoul(ver, (char **)NULL, 10);
}
varray_index++;
if (varray_index >= VERSIONARRAYLENGTH) {
*Lisp_errno = EIO;
return (0);
}
svarray++;
}
}
/*
* The last entry of varray is indicated by setting LASTVERSIONARRAY into
* version_no field.
*/
svarray->version_no = LASTVERSIONARRAY;
varray[varray_index].version_no = LASTVERSIONARRAY;

/*
* If more than one files have been stored in varray, we store the name
Expand All @@ -3132,7 +3138,7 @@ static int get_version_array(char *dir, char *file, FileName *varray, CurrentVAr
if (!NoFileP(varray)) {
strcpy(name, varray->name);
separate_version(name, ver, 1);
strcpy(svarray->name, name);
strcpy(varray[varray_index].name, name);
}

/*
Expand Down