Skip to content

Segfault / Stackoverflow when binaryen tries to match a pattern on names #7981

@mkustermann

Description

@mkustermann

See attached x.tar.gz

% tar xvzf x.tar.gz
x.wasm
% wasm-opt --enable-gc --enable-reference-types --enable-multivalue --enable-exception-handling --enable-nontrapping-float-to-int --enable-sign-ext --enable-bulk-memory --enable-threads '--no-inline=*<noInline>*' --closed-world --traps-never-happen --type-unfinalizing -Os --type-ssa --gufa -Os --type-merging -Os --type-finalizing --minimize-rec-groups -g x.wasm -o xx.wasm
zsh: segmentation fault (core dumped)  out/ReleaseX64/wasm-opt --enable-gc --enable-reference-types           -Os  

I think this happens because we pass --no-inline=*<noInline>*' pattern and some names are very long (60k characters).
Looking at the stack trace the pattern matching code is a recursive implementation that leads to a stack overflow.

The implementation doesn't seem particularly efficient:

bool wildcardMatch(const std::string& pattern, const std::string& value) {
  for (size_t i = 0; i < pattern.size(); i++) {
    if (pattern[i] == '*') {
      return wildcardMatch(pattern.substr(i + 1), value.substr(i)) ||
             (value.size() > 0 &&
              wildcardMatch(pattern.substr(i), value.substr(i + 1)));
    }
    if (i >= value.size()) {
      return false;
    }
    if (pattern[i] != value[i]) {
      return false;
    }
  }
  return value.size() == pattern.size();
}

When it sees a *x it could just scan forward in a tight loop to find the character x.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions