From 6d28e2286e834b1bde222059190182e8949c9148 Mon Sep 17 00:00:00 2001
From: "Vladimir V. Kisil" <kisilv@maths.leeds.ac.uk>
Date: Tue, 10 Sep 2019 10:55:44 +0100
Subject: [PATCH] Add archive_node::is_within_props() methods

It checks if an iterators points inside archive node properties.
Such checks prevent un-archiving of empty containers to add
random entries to their content.

Signed-off-by: Vladimir V. Kisil <kisilv@maths.leeds.ac.uk>
---
 ginac/archive.h     | 4 ++++
 ginac/container.h   | 3 ++-
 ginac/expairseq.cpp | 3 ++-
 ginac/matrix.cpp    | 5 +++--
 ginac/pseries.cpp   | 3 ++-
 5 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/ginac/archive.h b/ginac/archive.h
index 53c45437..7a19ddf6 100644
--- a/ginac/archive.h
+++ b/ginac/archive.h
@@ -117,6 +117,10 @@ public:
 	archive_node_cit find_first(const std::string &name) const;
 	archive_node_cit find_last(const std::string &name) const;
 
+	/** Check if iterator points inside of properties in archive_node
+	 */
+	inline bool is_within_props (archive_node_cit it) const { return it < props.end(); }
+
 	/** Retrieve property of type "ex" from node.
 	 *  @return "true" if property was found, "false" otherwise */
 	bool find_ex(const std::string &name, ex &ret, lst &sym_lst, unsigned index = 0) const;
diff --git a/ginac/container.h b/ginac/container.h
index 960f0729..9ab03f9c 100644
--- a/ginac/container.h
+++ b/ginac/container.h
@@ -214,7 +214,8 @@ public:
 
 		archive_node::archive_node_cit first = n.find_first("seq");
 		archive_node::archive_node_cit last = n.find_last("seq");
-		++last;
+		if (n.is_within_props(first))
+			++last;
 		this->reserve(this->seq, last - first);
 		for (archive_node::archive_node_cit i=first; i<last; ++i) {
 			ex e;
diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp
index a1361532..48e78584 100644
--- a/ginac/expairseq.cpp
+++ b/ginac/expairseq.cpp
@@ -114,7 +114,8 @@ void expairseq::read_archive(const archive_node &n, lst &sym_lst)
 	inherited::read_archive(n, sym_lst);
 	auto first = n.find_first("rest");
 	auto last = n.find_last("coeff");
-	++last;
+	if (n.is_within_props(first))
+		++last;
 	seq.reserve((last-first)/2);
 
 	for (auto loc = first; loc < last;) {
diff --git a/ginac/matrix.cpp b/ginac/matrix.cpp
index fb675060..cf148968 100644
--- a/ginac/matrix.cpp
+++ b/ginac/matrix.cpp
@@ -142,8 +142,9 @@ void matrix::read_archive(const archive_node &n, lst &sym_lst)
 	m.pop_back();
 	auto first = n.find_first("m");
 	auto last = n.find_last("m");
-	++last;
-	for (auto i=first; i != last; ++i) {
+	if (n.is_within_props(first))
+		++last;
+	for (auto i=first; i < last; ++i) {
 		ex e;
 		n.find_ex_by_loc(i, e, sym_lst);
 		m.push_back(e);
diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp
index 4dba5129..907da464 100644
--- a/ginac/pseries.cpp
+++ b/ginac/pseries.cpp
@@ -121,7 +121,8 @@ void pseries::read_archive(const archive_node &n, lst &sym_lst)
 	inherited::read_archive(n, sym_lst);
 	auto first = n.find_first("coeff");
 	auto last = n.find_last("power");
-	++last;
+	if (n.is_within_props(first))
+		++last;
 	seq.reserve((last-first)/2);
 
 	for (auto loc = first; loc < last;) {
-- 
2.23.0

