Skip to content

Commit e52d219

Browse files
committed
Fix buffer overflow in compilation
1 parent 516c9a8 commit e52d219

2 files changed

Lines changed: 41 additions & 29 deletions

File tree

src/manage/Compiler.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as fs from 'fs';
22
import * as os from 'os';
33
import * as path from 'path';
4-
import {exec, ExecException} from 'child_process';
4+
import {exec, ExecException, spawn} from 'child_process';
55
import {SourceMap} from '../sourcemap/SourceMap';
66
import * as readline from 'readline';
77
import {EventEmitter} from 'events';
@@ -94,17 +94,16 @@ export class WatCompiler extends Compiler {
9494
// compile WAT to Wasm
9595
return new Promise<CompileOutput>((resolve, reject) => {
9696
const file = `${dir}/upload.wasm`;
97-
const command = `${this.wabt}wat2wasm --no-canonicalize-leb128s --disable-bulk-memory --debug-names -v -o ${file} ${program}`;
97+
const command = `${this.wabt}wat2wasm`;
98+
const args = ['--no-canonicalize-leb128s', '--disable-bulk-memory', '--debug-names', '-v', '-o', file, program];
9899
let out: string = '';
99100
let err: string = '';
100101

101-
function handle(error: ExecException | null, stdout: string) {
102-
out = stdout;
103-
err = error?.message ?? '';
104-
}
102+
const compile = spawn(command, args);
103+
this.emit(CompilationEvents.started, `${command} ${args.join(' ')}`);
105104

106-
const compile = exec(command, handle);
107-
this.emit(CompilationEvents.started, command);
105+
compile.stdout.on('data', (data) => out += data.toString());
106+
compile.stderr.on('data', (data) => err += data.toString());
108107

109108
compile.on('close', (code) => {
110109
if (code !== 0) {
@@ -122,24 +121,28 @@ export class WatCompiler extends Compiler {
122121
public dump(output: CompileOutput): Promise<CompileOutput> {
123122
// object dump
124123
return new Promise<CompileOutput>((resolve, reject) => {
125-
const command = `${this.wabt}wasm-objdump -x -m ${output.file}`;
124+
const executable = `${this.wabt}wasm-objdump`;
125+
const args = ['-x', '-m', output.file];
126+
let stdout = '';
126127

127-
const compile = exec(command, (error: ExecException | null, stdout: string) => {
128-
output.map = this.parseWasmObjDump(output, stdout.toString());
129-
this.emit(CompilationEvents.sourcemap);
130-
resolve(output);
131-
});
128+
const dump = spawn(executable, args);
132129

133-
compile.on('close', (code) => {
130+
dump.stdout.on('data', (data) => stdout += data.toString());
131+
dump.on('error', (err) => reject(`wasm-objdump error: ${err.message}`));
132+
133+
dump.on('close', (code) => {
134134
if (code !== 0) {
135135
reject(`wasm-objdump exited with code ${code}`);
136136
return;
137137
}
138+
output.map = this.parseWasmObjDump(output, stdout);
139+
this.emit(CompilationEvents.sourcemap);
140+
resolve(output);
138141
});
139142
});
140143
}
141144

142-
public async map(program: string): Promise<CompileOutput> {
145+
public async map(program: string): Promise<CompileOutput> {
143146
return this.compile(program).then((output) => {
144147
return this.dump(output);
145148
});

src/sourcemap/SourceMapper.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {SourceMap} from './SourceMap';
2-
import {exec, ExecException} from 'child_process';
2+
import {spawn} from 'child_process';
33
import * as fs from 'fs';
44
import {MappingItem, SourceMapConsumer} from 'source-map';
55
import SourceLine = SourceMap.SourceLine;
@@ -32,27 +32,36 @@ export class WatMapper implements SourceMapper {
3232
let functions: Closure[];
3333
let globals: Variable[];
3434
let imports: Closure[];
35+
let stdout = '';
3536

36-
function handleObjDumpStreams(error: ExecException | null, stdout: string, stderr: string) {
37-
if (stderr.match('wasm-objdump')) {
37+
const [executable, ...args] = this.getNameDumpCommand();
38+
const objDump = spawn(executable, args);
39+
40+
objDump.stdout.on('data', (data) => stdout += data.toString());
41+
42+
objDump.stderr.on('data', (data) => {
43+
const text: string = data.toString();
44+
if (text.match('wasm-objdump')) {
3845
reject('Could not find wasm-objdump in the path');
39-
} else if (error) {
40-
reject(error.message);
4146
}
47+
});
4248

49+
objDump.on('error', (err) => reject(err.message));
50+
51+
const sourceMap = new SourceMap.Mapping().init(this.lineMapping, [], [], []);
52+
objDump.on('close', (code) => {
53+
if (code !== 0) {
54+
reject(`wasm-objdump exited with code ${code}`);
55+
return;
56+
}
4357
try {
4458
functions = WatMapper.getFunctionInfos(stdout);
4559
globals = WatMapper.getGlobalInfos(stdout);
4660
imports = WatMapper.getImportInfos(stdout);
4761
} catch (e) {
4862
reject(e);
63+
return;
4964
}
50-
}
51-
52-
const objDump = exec(this.getNameDumpCommand(), handleObjDumpStreams);
53-
54-
const sourceMap = new SourceMap.Mapping().init(this.lineMapping, [], [], []);
55-
objDump.on('close', () => {
5665
sourceMap.functions = functions;
5766
sourceMap.globals = globals;
5867
sourceMap.imports = imports;
@@ -137,8 +146,8 @@ export class WatMapper implements SourceMapper {
137146
return globals;
138147
}
139148

140-
private getNameDumpCommand(): string {
141-
return `${this.wabt}/wasm-objdump -x -m ${this.tmpdir}/upload.wasm`;
149+
private getNameDumpCommand(): string[] {
150+
return [`${this.wabt}/wasm-objdump`, '-x', '-m', `${this.tmpdir}/upload.wasm`];
142151
}
143152
}
144153

0 commit comments

Comments
 (0)