summaryrefslogtreecommitdiff
path: root/datatest.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2017-05-12 14:25:25 -0400
committerJeffrey Walton <noloader@gmail.com>2017-05-12 14:25:25 -0400
commit973de7712a63a7a08ffda24da3043e7f37f7f9aa (patch)
treed9efb31598653de80eb10f675b1573ae6a552841 /datatest.cpp
parent3f9667f3cd7541291705de413f37b7471ce5c6e5 (diff)
downloadcryptopp-git-973de7712a63a7a08ffda24da3043e7f37f7f9aa.tar.gz
Fix GetField for stray CR or LF
The test vector rsa_pkcs1_1_5.txt is the torture test. We calculated an incorrect index when a line continuation was part of a comment
Diffstat (limited to 'datatest.cpp')
-rw-r--r--datatest.cpp60
1 files changed, 46 insertions, 14 deletions
diff --git a/datatest.cpp b/datatest.cpp
index e15d795f..58be70be 100644
--- a/datatest.cpp
+++ b/datatest.cpp
@@ -656,6 +656,10 @@ void TestKeyDerivationFunction(TestData &v)
SignalTestFailure();
}
+// GetField parses the name/value pairs. The tricky part is the insertion operator
+// because Unix&Linux uses LF, OS X uses CR, and Windows uses CRLF. If this function
+// is modified, then run 'cryptest.exe tv rsa_pkcs1_1_5' as a test. Its the parser
+// file from hell. If it can be parsed without error, then things are likely OK.
bool GetField(std::istream &is, std::string &name, std::string &value)
{
// ***** Name *****
@@ -685,31 +689,59 @@ bool GetField(std::istream &is, std::string &name, std::string &value)
while (continueLine && std::getline(is, line))
{
- // Early out for immediately continuing a line
- if (!line.empty() && line[0] == '\\') { continue; }
+ // Unix and Linux may have a stray \r because of Windows
+ if (!line.empty() && (line[line.size() - 1] == '\r' || line[line.size() - 1] == '\n')) {
+ line.erase(line.size()-1);
+ }
- // Leading, trailing and temp position. The leading iterator moves right, and trailing
- // iterator moves left. The sub-string in the middle is the value for the name. The
- // value can be an empty string. One Plaintext is often empty for algorithm testing.
+ continueLine = false;
+ if (!line.empty())
+ {
+ // Early out for immediate line continuation
+ if (line[0] == '\\') {
+ continueLine = true;
+ continue;
+ }
+ // Check end of line. It must be last character
+ if (line[line.size() - 1] == '\\') {
+ continueLine = true;
+ }
+ }
+
+ // Leading, trailing and temp position. The leading position moves right, and
+ // trailing position moves left. The sub-string in the middle is the value for
+ // the name. We leave one space when line continuation is in effect, (and if
+ // present). The value can be an empty string. One Plaintext value is often
+ // empty for algorithm testing.
std::string::size_type l, t, p;
const std::string whitespace = " \r\n\t\v\f";
l = line.find_first_not_of(whitespace);
- if (l == std::string::npos) { break; }
- t = line.find_last_not_of(whitespace);
-
- continueLine = false;
- if (t != std::string::npos && line[t] == '\\') {
- continueLine = true;
- t = line.find_last_not_of(whitespace, t-1);
- }
+ if (l == std::string::npos) { l = 0; }
+ t = line.find_last_not_of(whitespace+"\\");
+ if (l == std::string::npos) { t = line.size(); }
+ // Chop comment. Perform after setting continueLine
p = line.find('#', l);
if (p < t) {
t = p;
- t = line.find_last_not_of(whitespace, t-1);
+ if (t) t--;
+ }
+
+ // Leave one whitespace if line continuation is in effect
+ if (continueLine)
+ {
+ if (l > 0 && ::isspace(line[l - 1]))
+ {
+ l--;
+ }
+ else if (t < line.size()-1 && ::isspace(line[t + 1]))
+ {
+ t++;
+ }
}
+ CRYPTOPP_ASSERT(t >= l);
value += line.substr(l, t - l + 1);
}