Rewrite entry parsing algorithm

Rewrite without regex crate.

The regex approach was broken. If the following _content_ was provided
in the entry:

    foo

    ---

    bar

The regex approach parsed the header until the "---" in the content.
This is, of course, not the way to do that.

Now, the parsing is implemented by hand. Should be faster as well,
though I don't care about this.

This fixes a severe bug.
This commit is contained in:
Matthias Beyer 2018-02-20 19:55:06 +01:00
parent b2048b3dcf
commit 9fb5f453fe
5 changed files with 21 additions and 25 deletions

View file

@ -58,6 +58,8 @@ This section contains the changelog from the last release to the next release.
default.
* `libimagerror` printed errors with `write!()` rather than `writeln!()`
when tracing.
* A parsing error in `libimagstore`, which caused the parsing of entries
with a line "---" in the content part to fail, was fixed.
## 0.6.1

View file

@ -21,7 +21,6 @@ maintenance = { status = "actively-developed" }
[dependencies]
glob = "0.2.11"
lazy_static = "0.2"
log = "0.4.0"
regex = "0.2"
semver = "0.8"

View file

@ -28,6 +28,7 @@ error_chain! {
foreign_links {
Io(::std::io::Error);
Fmt(::std::fmt::Error);
TomlDeserError(::toml::de::Error);
GlobPatternError(::glob::PatternError);
TomlQueryError(::toml_query::error::Error);

View file

@ -37,7 +37,6 @@
#[macro_use] extern crate log;
extern crate glob;
#[macro_use] extern crate lazy_static;
extern crate regex;
extern crate toml;
#[cfg(test)] extern crate tempdir;

View file

@ -17,13 +17,12 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
use regex::Regex;
use std::fmt::Write;
use toml::Value;
use store::Result;
use store::Header;
use error::StoreErrorKind as SEK;
use error::StoreError as SE;
#[cfg(feature = "early-panic")]
#[macro_export]
@ -43,27 +42,23 @@ macro_rules! if_cfg_panic {
pub fn entry_buffer_to_header_content(buf: &str) -> Result<(Value, String)> {
debug!("Building entry from string");
lazy_static! {
static ref RE: Regex = Regex::new(r"(?smx)
^---$
(?P<header>.*) # Header
^---$\n
(?P<content>.*) # Content
").unwrap();
let mut header = String::new();
let mut content = String::new();
let mut header_consumed = false;
for line in buf.lines().skip(1) { // the first line is "---"
if line == "---" {
header_consumed = true;
// do not further process the line
} else {
if !header_consumed {
let _ = writeln!(header, "{}", line)?;
} else {
let _ = write!(content, "{}", line)?;
}
}
}
let matches = match RE.captures(buf) {
None => return Err(SE::from_kind(SEK::MalformedEntry)),
Some(s) => s,
};
let header = match matches.name("header") {
None => return Err(SE::from_kind(SEK::MalformedEntry)),
Some(s) => s
};
let content = matches.name("content").map(|r| r.as_str()).unwrap_or("");
Ok((Value::parse(header.as_str())?, String::from(content)))
Ok((Value::parse(&header)?, String::from(content)))
}