Validate regular expressions before reading input

This commit is contained in:
2026-07-10 18:13:27 -05:00
parent 572cbc9387
commit 5709f54081
4 changed files with 54 additions and 2 deletions
+23
View File
@@ -1,4 +1,5 @@
#include "sedpp/Compiler.h"
#include "sedpp/Regex.h"
#include <cctype>
#include <iostream>
@@ -103,6 +104,28 @@ Program Compiler::compile(const std::vector<std::string> &scripts) {
if (braceDepth_ > 0) {
throw std::runtime_error("-e expression #1, char 0: unmatched '{'");
}
// Validate every literal regular expression before Runner opens or reads an
// input stream. Besides matching GNU sed's diagnostic timing, this matters
// for portability probes such as `(sed non_gnu_re || sed fallback_re)`: the
// rejected first expression must leave the shared pipe untouched so the
// fallback process can consume it. Empty expressions are runtime references
// to the previously used regex and therefore cannot be compiled here.
auto validateAddress = [this](const std::optional<Address> &address) {
if (address && address->kind == AddressKind::Regex &&
!address->text.empty()) {
Regex regex(address->text, options_);
}
};
for (const Command &command : program_.commands) {
validateAddress(command.firstAddress);
validateAddress(command.secondAddress);
if (command.substitute && !command.substitute->pattern.empty()) {
Regex regex(command.substitute->pattern, options_,
command.substitute->ignoreCase,
command.substitute->multiline);
}
}
return program_;
}
+1 -1
View File
@@ -7,7 +7,7 @@
#include <cstdlib>
namespace sedpp {
int SEDPP_VERSION = 1;
constexpr const char *SEDPP_VERSION = "1.0.1";
void OptionParser::printVersion() {
// Version output intentionally names this implementation, not GNU sed.