Skip to content

Commit

Permalink
Fixed encode/decode not this-bound
Browse files Browse the repository at this point in the history
Moved encoding to compat layer
  • Loading branch information
james-pre committed Oct 24, 2023
1 parent a54313c commit c16320e
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 66 deletions.
10 changes: 5 additions & 5 deletions src/backends/AsyncMirror.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,10 @@ export class AsyncMirror extends SynchronousFileSystem {

public _syncSync(fd: PreloadFile<AsyncMirror>) {
const stats = fd.getStats();
this._sync.writeFileSync(fd.getPath(), fd.getBuffer(), null, FileFlag.getFileFlag('w'), stats.mode, stats.getCred(0, 0));
this._sync.writeFileSync(fd.getPath(), fd.getBuffer(), FileFlag.getFileFlag('w'), stats.mode, stats.getCred(0, 0));
this.enqueueOp({
apiMethod: 'writeFile',
arguments: [fd.getPath(), fd.getBuffer(), null, fd.getFlag(), stats.mode, stats.getCred(0, 0)],
arguments: [fd.getPath(), fd.getBuffer(), fd.getFlag(), stats.mode, stats.getCred(0, 0)],
});
}

Expand All @@ -174,7 +174,7 @@ export class AsyncMirror extends SynchronousFileSystem {
// Sanity check: Is this open/close permitted?
const fd = this._sync.openSync(p, flag, mode, cred);
fd.closeSync();
return new MirrorFile(this, p, flag, this._sync.statSync(p, cred), <Uint8Array>this._sync.readFileSync(p, null, FileFlag.getFileFlag('r'), cred));
return new MirrorFile(this, p, flag, this._sync.statSync(p, cred), this._sync.readFileSync(p, FileFlag.getFileFlag('r'), cred));
}

public unlinkSync(p: string, cred: Cred): void {
Expand Down Expand Up @@ -250,8 +250,8 @@ export class AsyncMirror extends SynchronousFileSystem {
}
},
copyFile = async (p: string, mode: number): Promise<void> => {
const data = await this._async.readFile(p, null, FileFlag.getFileFlag('r'), Cred.Root);
this._sync.writeFileSync(p, data, null, FileFlag.getFileFlag('w'), mode, Cred.Root);
const data = await this._async.readFile(p, FileFlag.getFileFlag('r'), Cred.Root);
this._sync.writeFileSync(p, data, FileFlag.getFileFlag('w'), mode, Cred.Root);
},
copyItem = async (p: string): Promise<void> => {
const stats = await this._async.stat(p, Cred.Root);
Expand Down
26 changes: 13 additions & 13 deletions src/backends/Locked.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Mutex from '../mutex.js';
import { FileContents, FileSystem, FileSystemMetadata } from '../filesystem.js';
import { FileSystem, FileSystemMetadata } from '../filesystem.js';
import { FileFlag } from '../file.js';
import { Stats } from '../stats.js';
import { File } from '../file.js';
Expand Down Expand Up @@ -188,44 +188,44 @@ export default class LockedFS<T extends FileSystem> implements FileSystem {
return this._fs.truncateSync(p, len, cred);
}

public async readFile(fname: string, encoding: BufferEncoding, flag: FileFlag, cred: Cred): Promise<FileContents> {
public async readFile(fname: string, flag: FileFlag, cred: Cred): Promise<Uint8Array> {
await this._mu.lock(fname);
const data = await this._fs.readFile(fname, encoding, flag, cred);
const data = await this._fs.readFile(fname, flag, cred);
this._mu.unlock(fname);
return data;
}

public readFileSync(fname: string, encoding: BufferEncoding, flag: FileFlag, cred: Cred): FileContents {
public readFileSync(fname: string, flag: FileFlag, cred: Cred): Uint8Array {
if (this._mu.isLocked(fname)) {
throw new Error('invalid sync call');
}
return this._fs.readFileSync(fname, encoding, flag, cred);
return this._fs.readFileSync(fname, flag, cred);
}

public async writeFile(fname: string, data: FileContents, encoding: BufferEncoding, flag: FileFlag, mode: number, cred: Cred): Promise<void> {
public async writeFile(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred): Promise<void> {
await this._mu.lock(fname);
await this._fs.writeFile(fname, data, encoding, flag, mode, cred);
await this._fs.writeFile(fname, data, flag, mode, cred);
this._mu.unlock(fname);
}

public writeFileSync(fname: string, data: FileContents, encoding: BufferEncoding, flag: FileFlag, mode: number, cred: Cred): void {
public writeFileSync(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred): void {
if (this._mu.isLocked(fname)) {
throw new Error('invalid sync call');
}
return this._fs.writeFileSync(fname, data, encoding, flag, mode, cred);
return this._fs.writeFileSync(fname, data, flag, mode, cred);
}

public async appendFile(fname: string, data: FileContents, encoding: BufferEncoding, flag: FileFlag, mode: number, cred: Cred): Promise<void> {
public async appendFile(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred): Promise<void> {
await this._mu.lock(fname);
await this._fs.appendFile(fname, data, encoding, flag, mode, cred);
await this._fs.appendFile(fname, data, flag, mode, cred);
this._mu.unlock(fname);
}

public appendFileSync(fname: string, data: FileContents, encoding: BufferEncoding, flag: FileFlag, mode: number, cred: Cred): void {
public appendFileSync(fname: string, data: Uint8Array, flag: FileFlag, mode: number, cred: Cred): void {
if (this._mu.isLocked(fname)) {
throw new Error('invalid sync call');
}
return this._fs.appendFileSync(fname, data, encoding, flag, mode, cred);
return this._fs.appendFileSync(fname, data, flag, mode, cred);
}

public async chmod(p: string, mode: number, cred: Cred): Promise<void> {
Expand Down
23 changes: 12 additions & 11 deletions src/backends/OverlayFS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import LockedFS from './Locked.js';
import { resolve, dirname } from '../emulation/path.js';
import { Cred } from '../cred.js';
import { CreateBackend, type BackendOptions } from './backend.js';
import { decode, encode } from '../utils.js';
/**
* @internal
*/
Expand Down Expand Up @@ -127,13 +128,13 @@ export class UnlockedOverlayFS extends BaseFileSystem {
public async _syncAsync(file: PreloadFile<UnlockedOverlayFS>): Promise<void> {
const stats = file.getStats();
await this.createParentDirectoriesAsync(file.getPath(), stats.getCred(0, 0));
return this._writable.writeFile(file.getPath(), file.getBuffer(), null, getFlag('w'), stats.mode, stats.getCred(0, 0));
return this._writable.writeFile(file.getPath(), file.getBuffer(), getFlag('w'), stats.mode, stats.getCred(0, 0));
}

public _syncSync(file: PreloadFile<UnlockedOverlayFS>): void {
const stats = file.getStats();
this.createParentDirectories(file.getPath(), stats.getCred(0, 0));
this._writable.writeFileSync(file.getPath(), file.getBuffer(), null, getFlag('w'), stats.mode, stats.getCred(0, 0));
this._writable.writeFileSync(file.getPath(), file.getBuffer(), getFlag('w'), stats.mode, stats.getCred(0, 0));
}

/**
Expand All @@ -149,8 +150,8 @@ export class UnlockedOverlayFS extends BaseFileSystem {

// Read deletion log, process into metadata.
try {
const data = (await this._writable.readFile(deletionLogPath, 'utf8', getFlag('r'), Cred.Root)) as string;
this._deleteLog = data;
const data = await this._writable.readFile(deletionLogPath, getFlag('r'), Cred.Root);
this._deleteLog = decode(data);
} catch (err) {
if (err.errno !== ErrorCode.ENOENT) {
throw err;
Expand Down Expand Up @@ -219,7 +220,7 @@ export class UnlockedOverlayFS extends BaseFileSystem {
throw ApiError.EISDIR(newPath);
}

await this.writeFile(newPath, await this.readFile(oldPath, null, getFlag('r'), cred), null, getFlag('w'), oldStats.mode, cred);
await this.writeFile(newPath, await this.readFile(oldPath, getFlag('r'), cred), getFlag('w'), oldStats.mode, cred);
}

if (oldPath !== newPath && (await this.exists(oldPath, cred))) {
Expand Down Expand Up @@ -276,7 +277,7 @@ export class UnlockedOverlayFS extends BaseFileSystem {
throw ApiError.EISDIR(newPath);
}

this.writeFileSync(newPath, this.readFileSync(oldPath, null, getFlag('r'), cred), null, getFlag('w'), oldStats.mode, cred);
this.writeFileSync(newPath, this.readFileSync(oldPath, getFlag('r'), cred), getFlag('w'), oldStats.mode, cred);
}

if (oldPath !== newPath && this.existsSync(oldPath, cred)) {
Expand Down Expand Up @@ -332,7 +333,7 @@ export class UnlockedOverlayFS extends BaseFileSystem {
return this._writable.open(p, flag, mode, cred);
} else {
// Create an OverlayFile.
const buf = await this._readable.readFile(p, null, getFlag('r'), cred);
const buf = await this._readable.readFile(p, getFlag('r'), cred);
const stats = Stats.clone(await this._readable.stat(p, cred));
stats.mode = mode;
return new OverlayFile(this, p, flag, stats, buf as Uint8Array);
Expand Down Expand Up @@ -367,7 +368,7 @@ export class UnlockedOverlayFS extends BaseFileSystem {
return this._writable.openSync(p, flag, mode, cred);
} else {
// Create an OverlayFile.
const buf = <Uint8Array>this._readable.readFileSync(p, null, getFlag('r'), cred);
const buf = <Uint8Array>this._readable.readFileSync(p, getFlag('r'), cred);
const stats = Stats.clone(this._readable.statSync(p, cred));
stats.mode = mode;
return new OverlayFile(this, p, flag, stats, buf);
Expand Down Expand Up @@ -594,7 +595,7 @@ export class UnlockedOverlayFS extends BaseFileSystem {
} else {
this._deleteLogUpdatePending = true;
this._writable
.writeFile(deletionLogPath, this._deleteLog, 'utf8', FileFlag.getFileFlag('w'), 0o644, cred)
.writeFile(deletionLogPath, encode(this._deleteLog), FileFlag.getFileFlag('w'), 0o644, cred)
.then(() => {
if (this._deleteLogUpdateNeeded) {
this._deleteLogUpdateNeeded = false;
Expand Down Expand Up @@ -702,7 +703,7 @@ export class UnlockedOverlayFS extends BaseFileSystem {
if (pStats.isDirectory()) {
this._writable.mkdirSync(p, pStats.mode, cred);
} else {
this.writeFileSync(p, this._readable.readFileSync(p, null, getFlag('r'), cred), null, getFlag('w'), pStats.mode, cred);
this.writeFileSync(p, this._readable.readFileSync(p, getFlag('r'), cred), getFlag('w'), pStats.mode, cred);
}
}

Expand All @@ -711,7 +712,7 @@ export class UnlockedOverlayFS extends BaseFileSystem {
if (pStats.isDirectory()) {
await this._writable.mkdir(p, pStats.mode, cred);
} else {
await this.writeFile(p, await this._readable.readFile(p, null, getFlag('r'), cred), null, getFlag('w'), pStats.mode, cred);
await this.writeFile(p, await this._readable.readFile(p, getFlag('r'), cred), getFlag('w'), pStats.mode, cred);
}
}
}
Expand Down
23 changes: 19 additions & 4 deletions src/emulation/promises.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { File, FileFlag } from '../file.js';
import { normalizePath, normalizeMode, getFdForFile, normalizeOptions, fd2file, fdMap, normalizeTime, cred, nop, resolveFS, fixError, mounts } from './shared.js';
import { FileContents, FileSystem } from '../filesystem.js';
import { Stats } from '../stats.js';
import { encode } from '../utils.js';
import { decode, encode } from '../utils.js';

type FileSystemMethod = {
[K in keyof FileSystem]: FileSystem[K] extends (...args: any) => any
Expand Down Expand Up @@ -154,7 +154,14 @@ export async function readFile(filename: string, arg2: any = {}): Promise<Uint8A
if (!flag.isReadable()) {
throw new ApiError(ErrorCode.EINVAL, 'Flag passed to readFile must allow for reading.');
}
return doOp('readFile', true, filename, options.encoding, flag, cred);
const data: Uint8Array = await doOp('readFile', true, filename, flag, cred);
switch (options.encoding) {
case 'utf8':
case 'utf-8':
return decode(data);
default:
return data;
}
}

/**
Expand All @@ -178,7 +185,11 @@ export async function writeFile(filename: string, data: FileContents, arg3?: { e
if (!flag.isWriteable()) {
throw new ApiError(ErrorCode.EINVAL, 'Flag passed to writeFile must allow for writing.');
}
return doOp('writeFile', true, filename, data, options.encoding, flag, options.mode, cred);
if (typeof data != 'string' && !options.encoding) {
throw new ApiError(ErrorCode.EINVAL, 'Encoding not specified');
}
const encodedData = typeof data == 'string' ? encode(data) : data;
return doOp('writeFile', true, filename, encodedData, flag, options.mode, cred);
}

/**
Expand All @@ -205,7 +216,11 @@ export async function appendFile(filename: string, data: FileContents, arg3?: an
if (!flag.isAppendable()) {
throw new ApiError(ErrorCode.EINVAL, 'Flag passed to appendFile must allow for appending.');
}
return doOp('appendFile', true, filename, data, options.encoding, flag, options.mode, cred);
if (typeof data != 'string' && !options.encoding) {
throw new ApiError(ErrorCode.EINVAL, 'Encoding not specified');
}
const encodedData = typeof data == 'string' ? encode(data) : data;
return doOp('appendFile', true, filename, encodedData, flag, options.mode, cred);
}

// FILE DESCRIPTOR METHODS
Expand Down
23 changes: 19 additions & 4 deletions src/emulation/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { FileContents, FileSystem } from '../filesystem.js';
import { Stats } from '../stats.js';
import type { symlink, ReadSyncOptions } from 'fs';
import { normalizePath, cred, getFdForFile, normalizeMode, normalizeOptions, fdMap, fd2file, normalizeTime, resolveFS, fixError, mounts } from './shared.js';
import { encode } from '../utils.js';
import { decode, encode } from '../utils.js';

type FileSystemMethod = {
[K in keyof FileSystem]: FileSystem[K] extends (...args: any) => any
Expand Down Expand Up @@ -135,7 +135,14 @@ export function readFileSync(filename: string, arg2: { encoding: string; flag?:
if (!flag.isReadable()) {
throw new ApiError(ErrorCode.EINVAL, 'Flag passed to readFile must allow for reading.');
}
return doOp('readFileSync', true, filename, options.encoding, flag, cred);
const data: Uint8Array = doOp('readFileSync', true, filename, flag, cred);
switch (options.encoding) {
case 'utf8':
case 'utf-8':
return decode(data);
default:
return data;
}
}

/**
Expand All @@ -158,7 +165,11 @@ export function writeFileSync(filename: string, data: FileContents, arg3?: { enc
if (!flag.isWriteable()) {
throw new ApiError(ErrorCode.EINVAL, 'Flag passed to writeFile must allow for writing.');
}
return doOp('writeFileSync', true, filename, data, options.encoding, flag, options.mode, cred);
if (typeof data != 'string' && !options.encoding) {
throw new ApiError(ErrorCode.EINVAL, 'Encoding not specified');
}
const encodedData = typeof data == 'string' ? encode(data) : data;
return doOp('writeFileSync', true, filename, encodedData, flag, options.mode, cred);
}

/**
Expand All @@ -185,7 +196,11 @@ export function appendFileSync(filename: string, data: FileContents, arg3?: { en
if (!flag.isAppendable()) {
throw new ApiError(ErrorCode.EINVAL, 'Flag passed to appendFile must allow for appending.');
}
return doOp('appendFileSync', true, filename, data, options.encoding, flag, options.mode, cred);
if (typeof data != 'string' && !options.encoding) {
throw new ApiError(ErrorCode.EINVAL, 'Encoding not specified');
}
const encodedData = typeof data == 'string' ? encode(data) : data;
return doOp('appendFileSync', true, filename, encodedData, flag, options.mode, cred);
}

/**
Expand Down
Loading

0 comments on commit c16320e

Please sign in to comment.