Validate regular expressions before reading input
This commit is contained in:
@@ -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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user