Skip to content

Commit 992584f

Browse files
Fix segment fault in API BinaryenModuleParse (#5440) (#5441)
We cannot modify the input string safely. To avoid that, copy where needed. Fixes #5440
1 parent 4471b81 commit 992584f

File tree

3 files changed

+16
-14
lines changed

3 files changed

+16
-14
lines changed

src/binaryen-c.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5453,7 +5453,7 @@ void BinaryenModuleSetFeatures(BinaryenModuleRef module,
54535453
BinaryenModuleRef BinaryenModuleParse(const char* text) {
54545454
auto* wasm = new Module;
54555455
try {
5456-
SExpressionParser parser(const_cast<char*>(text));
5456+
SExpressionParser parser(text);
54575457
Element& root = *parser.root;
54585458
SExpressionWasmBuilder builder(*wasm, *root[0], IRProfile::Normal);
54595459
} catch (ParseException& p) {

src/wasm-s-parser.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,16 @@ class Element {
9191
// Generic S-Expression parsing into lists
9292
//
9393
class SExpressionParser {
94-
char* input;
94+
const char* input;
9595
size_t line;
96-
char* lineStart;
96+
char const* lineStart;
9797
SourceLocation* loc = nullptr;
9898

9999
MixedArena allocator;
100100

101101
public:
102102
// Assumes control of and modifies the input.
103-
SExpressionParser(char* input);
103+
SExpressionParser(const char* input);
104104
Element* root;
105105

106106
private:

src/wasm/wasm-s-parser.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ void Element::dump() {
140140
std::cout << "dumping " << this << " : " << *this << ".\n";
141141
}
142142

143-
SExpressionParser::SExpressionParser(char* input) : input(input) {
143+
SExpressionParser::SExpressionParser(char const* input) : input(input) {
144144
root = nullptr;
145145
line = 1;
146146
lineStart = input;
@@ -190,23 +190,23 @@ Element* SExpressionParser::parse() {
190190

191191
void SExpressionParser::parseDebugLocation() {
192192
// Extracting debug location (if valid)
193-
char* debugLoc = input + 3; // skipping ";;@"
193+
char const* debugLoc = input + 3; // skipping ";;@"
194194
while (debugLoc[0] && debugLoc[0] == ' ') {
195195
debugLoc++;
196196
}
197-
char* debugLocEnd = debugLoc;
197+
char const* debugLocEnd = debugLoc;
198198
while (debugLocEnd[0] && debugLocEnd[0] != '\n') {
199199
debugLocEnd++;
200200
}
201-
char* pos = debugLoc;
201+
char const* pos = debugLoc;
202202
while (pos < debugLocEnd && pos[0] != ':') {
203203
pos++;
204204
}
205205
if (pos >= debugLocEnd) {
206206
return; // no line number
207207
}
208208
std::string name(debugLoc, pos);
209-
char* lineStart = ++pos;
209+
char const* lineStart = ++pos;
210210
while (pos < debugLocEnd && pos[0] != ':') {
211211
pos++;
212212
}
@@ -279,7 +279,7 @@ Element* SExpressionParser::parseString() {
279279
input++;
280280
dollared = true;
281281
}
282-
char* start = input;
282+
char const* start = input;
283283
if (input[0] == '"') {
284284
// parse escaping \", but leave code escaped - we'll handle escaping in
285285
// memory segments specifically
@@ -317,12 +317,14 @@ Element* SExpressionParser::parseString() {
317317
if (start == input) {
318318
throw ParseException("expected string", line, input - lineStart);
319319
}
320-
char temp = input[0];
321-
input[0] = 0;
320+
321+
std::string temp;
322+
temp.assign(start, input - start);
323+
322324
auto ret = allocator.alloc<Element>()
323-
->setString(IString(start, false), dollared, false)
325+
->setString(IString(temp.c_str(), false), dollared, false)
324326
->setMetadata(line, start - lineStart, loc);
325-
input[0] = temp;
327+
326328
return ret;
327329
}
328330

0 commit comments

Comments
 (0)