Skip to content

Commit

Permalink
Fix server crash when invoking *DIR with no arguments.
Browse files Browse the repository at this point in the history
(Interface/implementation mismatch. See https://stackoverflow.com/a/61271104)
  • Loading branch information
Tom Seddon committed Dec 12, 2024
1 parent 71028b4 commit 99f034c
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 36 deletions.
3 changes: 2 additions & 1 deletion server/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,5 +331,6 @@ module.exports = {

// Doesn't seem worth enforcing.
"arrow-body-style": "off"
}
},
ignorePatterns: ['.eslintrc.js'],
};
42 changes: 21 additions & 21 deletions server/beebfs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,44 +437,44 @@ export interface IFSState {

// get current drive. (OSGBPB 6 reads this, so it's part of the standard
// interface.)
getCurrentDrive(): string;
getCurrentDrive: () => string;

// get current directory. (OSGBPB 6 reads this, so it's part of the standard
// interface.)
getCurrentDir(): string;
getCurrentDir: () => string;

// get library drive. (OSGBPB 7 reads this, so it's part of the standard
// interface.)
getLibraryDrive(): string;
getLibraryDrive: () => string;

// get library directory. (OSGBPB 7 reads this, so it's part of the standard
// interface.)
getLibraryDir(): string;
getLibraryDir: () => string;

// get object holding current transient settings that would be reset on
// Ctrl+Break - drive/dir, lib drive/dir, and so on. Use when recreating the
// state, to restore the current settings.
//
// The naming is crappy because 'state' was already taken.
getTransientSettings(): unknown;
getTransientSettings: () => unknown;

// turns transient settings into a human-readable string for printing on the
// Beeb. This isn't a toString on an interface type, so the FS state has the
// option of printing something useful out when there's no state.
getTransientSettingsString(transientSettings: unknown): string;
getTransientSettingsString: (transientSettings: unknown) => string;

// get object holding current persistent settings, that would not be reset
// on Ctrl+Break - drive assignments, and so on. Use when recreating the
// state, to restore the current settings.
getPersistentSettings(): unknown;
getPersistentSettings: () => unknown;

// turns persistent settings into a human-readable string for printing on
// the Beeb.
getPersistentSettingsString(persistentSettings: unknown): string;
getPersistentSettingsString: (persistentSettings: unknown) => string;

// get file to use for *RUN. If tryLibDir is false, definitely don't try lib
// drive/directory.
getFileForRUN(fqn: FQN, tryLibDir: boolean): Promise<File | undefined>;
getFileForRUN: (fqn: FQN, tryLibDir: boolean) => Promise<File | undefined>;

// get *CAT text, given command line. Handle default case, when
// commandLine===undefined, and any straightforward special cases that would
Expand All @@ -484,40 +484,40 @@ export interface IFSState {
// If returning undefined, the BeebFS class will try to interpret the
// command line as a FSP and use the resulting volume's handler type to
// catalogue an appropriate drive based on that.
getCAT(commandLine: string | undefined): Promise<string | undefined>;
getCAT: (commandLine: string | undefined) => Promise<string | undefined>;

// handle *DRIVE/*MOUNT.
starDrive(arg: string | undefined): void;
starDrive: (arg: string | undefined) => void;

// handle *DIR.
starDir(filePath: FilePath | undefined): void;
starDir: (filePath: FilePath | undefined) => void;

// handle *LIB.
starLib(filePath: FilePath | undefined): void;
starLib: (filePath: FilePath | undefined) => void;

// handle *HSTATUS drives output.
getDrivesOutput(): Promise<string>;
getDrivesOutput: () => Promise<string>;

// read boot option, for OSGBPB 5 or SHIFT+BREAK.
getBootOption(): Promise<number>;
getBootOption: () => Promise<number>;

// handle *OPT 4.
setBootOption(option: number): Promise<void>;
setBootOption: (option: number) => Promise<void>;

// handle *TITLE.
setTitle(title: string): Promise<void>;
setTitle: (title: string) => Promise<void>;

// read title, for OSGBPB 5.
getTitle(): Promise<string>;
getTitle: () => Promise<string>;

// read names, for OSGBPB 6.
readNames(): Promise<string[]>;
readNames: () => Promise<string[]>;

// return list of type-specific commands.
//
// This is only called when the FS type potentially changes, so it's OK if
// it does something expensive.
getCommands(): server.Command[];
getCommands: () => server.Command[];
}

/////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -674,7 +674,7 @@ export class FS {

private state: IFSState | undefined;
private stateCommands: undefined | server.Command[];
private defaultTransientSettings: unknown ;
private defaultTransientSettings: unknown;

private gaManipulator: gitattributes.Manipulator | undefined;

Expand Down
20 changes: 14 additions & 6 deletions server/dfsType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class DFSState implements beebfs.IFSState {
return undefined;
}

public getPersistentSettingsString(_settings: undefined): string {
public getPersistentSettingsString(_settings: unknown): string {
return '';
}

Expand Down Expand Up @@ -219,12 +219,20 @@ class DFSState implements beebfs.IFSState {
return true;
}

public starDir(filePath: beebfs.FilePath): void {
this.current = this.getDFSPathFromFilePath(filePath);
public starDir(filePath: beebfs.FilePath | undefined): void {
if (filePath !== undefined) {
this.current = this.getDFSPathFromFilePath(filePath);
}
}

public starLib(filePath: beebfs.FilePath): void {
this.library = this.getDFSPathFromFilePath(filePath);
public starLib(filePath: beebfs.FilePath | undefined): void {
if (filePath !== undefined) {
this.library = this.getDFSPathFromFilePath(filePath);
} else {
// This is what DFS 2.45 does, and BeebLink's DFS mode is trying to
// copy DFS...
this.library = gDefaultTransientSettings.library;
}
}

public async getDrivesOutput(): Promise<string> {
Expand Down Expand Up @@ -314,7 +322,7 @@ class DFSType implements beebfs.IFSType {
return c >= 32 && c < 127;
}

public async createState(volume: beebfs.Volume, transientSettings: unknown , persistentSettings: unknown , log: utils.Log | undefined): Promise<beebfs.IFSState> {
public async createState(volume: beebfs.Volume, transientSettings: unknown, persistentSettings: unknown, log: utils.Log | undefined): Promise<beebfs.IFSState> {
return new DFSState(volume, transientSettings, log);
}

Expand Down
6 changes: 3 additions & 3 deletions server/pcType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ class PCState implements beebfs.IFSState {
return errors.badDrive();
}

public starDir(_filePath: beebfs.FilePath): void {
public starDir(_filePath: beebfs.FilePath | undefined): void {
return notSupported();
}

public starLib(_filePath: beebfs.FilePath): void {
public starLib(_filePath: beebfs.FilePath | undefined): void {
return notSupported();
}

Expand Down Expand Up @@ -155,7 +155,7 @@ class PCState implements beebfs.IFSState {
class PCType implements beebfs.IFSType {
public readonly name = 'PC';

public async createState(volume: beebfs.Volume, transientSettings: unknown , persistentSettings: unknown , log: utils.Log | undefined): Promise<beebfs.IFSState> {
public async createState(volume: beebfs.Volume, transientSettings: unknown, persistentSettings: unknown, log: utils.Log | undefined): Promise<beebfs.IFSState> {
return new PCState(volume, log);
}

Expand Down
2 changes: 1 addition & 1 deletion server/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@
"./speedtest.ts",
"./tubeHostType.ts",
"./utils.ts",
"./volumebrowser.ts",
"./volumebrowser.ts"
]
}
12 changes: 8 additions & 4 deletions server/tubeHostType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,12 +572,16 @@ class TubeHostState implements beebfs.IFSState {
return true;
}

public starDir(filePath: beebfs.FilePath): void {
this.current = this.getTubeHostPathFromFilePath(filePath);
public starDir(filePath: beebfs.FilePath | undefined): void {
if (filePath !== undefined) {
this.current = this.getTubeHostPathFromFilePath(filePath);
}
}

public starLib(filePath: beebfs.FilePath): void {
this.library = this.getTubeHostPathFromFilePath(filePath);
public starLib(filePath: beebfs.FilePath | undefined): void {
if (filePath !== undefined) {
this.library = this.getTubeHostPathFromFilePath(filePath);
}
}

public async getDrivesOutput(): Promise<string> {
Expand Down

0 comments on commit 99f034c

Please sign in to comment.