http://bugzilla.lyx.org/show_bug.cgi?id=3764

This is an important privacy bug, that should be fixed before 1..50
IMO. In the following patch, I tried to be as unintrusive as possible.
The idea is that before writing the buffer params, the whole document
is scanned to determine what are the authors of existing changes. The
other authors of the list are replaced by empty entries. Indeed, it is
not possible/easy to renumber the authors on the fly if I want to
remove one of them. OTOH, the \author entries do not contain an author
id, and it is therefore necessary to insert empty authors for unused
ids.

I do not like this patch very much, actually %-| The name AuthorActive
is ugly, the class definition in Author.h is weird (but better IMO
than including <map> everywhere).

Finally, I think that a policy should be defined in AuthorList to reuse empty
author entries.

Nevertheless, the patch seems to fit the bill. Please please test it,
I am not sure at all I did not make mistakes. 

Comments welcome.

JMarc

Index: src/Changes.cpp
===================================================================
--- src/Changes.cpp	(révision 18972)
+++ src/Changes.cpp	(copie de travail)
@@ -26,8 +26,8 @@ namespace lyx {
 
 using std::abs;
 using std::endl;
-using std::string;
 using std::max;
+using std::string;
 
 /*
  * Class Change has a changetime field that specifies the exact time at which
@@ -357,4 +357,13 @@ void Changes::lyxMarkChange(std::ostream
 }
 
 
+void Changes::checkAuthors(AuthorActive & author_active)
+{
+	ChangeTable::const_iterator it = table_.begin();
+	ChangeTable::const_iterator endit = table_.end();
+	for ( ; it != endit ; ++it) 
+		if (it->change.type != Change::UNCHANGED)
+			author_active[it->change.author] = true;
+}
+
 } // namespace lyx
Index: src/buffer_funcs.h
===================================================================
--- src/buffer_funcs.h	(révision 18972)
+++ src/buffer_funcs.h	(copie de travail)
@@ -22,6 +22,7 @@ namespace lyx {
 
 namespace support { class FileName; }
 
+class AuthorActive;
 class Buffer;
 class DocIterator;
 class ErrorList;
@@ -75,6 +76,11 @@ void updateLabels(Buffer const &, bool c
 ///
 void checkBufferStructure(Buffer &, ParIterator const &);
 
+/// For each author, sets author_active to true if there is a change
+/// by this author in the document.
+void checkAuthors(Buffer const & buffer, AuthorActive & author_active);
+
+
 } // namespace lyx
 
 #endif // BUFFER_FUNCS_H
Index: src/buffer_funcs.cpp
===================================================================
--- src/buffer_funcs.cpp	(révision 18972)
+++ src/buffer_funcs.cpp	(copie de travail)
@@ -757,4 +757,14 @@ void checkBufferStructure(Buffer & buffe
 	}
 }
 
+
+void checkAuthors(Buffer const & buf, AuthorActive & author_active) 
+{
+	ParIterator const end = par_iterator_end(buf.inset());
+	ParIterator it = par_iterator_begin(buf.inset());
+	for ( ; it != end; ++it) {
+		it->checkAuthors(author_active);
+	}
+}
+
 } // namespace lyx
Index: src/BufferParams.h
===================================================================
--- src/BufferParams.h	(révision 18972)
+++ src/BufferParams.h	(copie de travail)
@@ -67,7 +67,7 @@ public:
 	std::string const readToken(Lexer & lex, std::string const & token);
 
 	///
-	void writeFile(std::ostream &) const;
+	void writeFile(std::ostream &, AuthorActive & author_active) const;
 
 	/** \returns true if the babel package is used (interogates
 	 *  the BufferParams and a LyXRC variable).
Index: src/frontends/controllers/ControlDocument.cpp
===================================================================
--- src/frontends/controllers/ControlDocument.cpp	(révision 18972)
+++ src/frontends/controllers/ControlDocument.cpp	(copie de travail)
@@ -97,8 +97,9 @@ void dispatch_bufferparams(Kernel const 
 			   kb_action lfun)
 {
 	ostringstream ss;
+	AuthorActive author_active;
 	ss << "\\begin_header\n";
-	bp.writeFile(ss);
+	bp.writeFile(ss, author_active);
 	ss << "\\end_header\n";
 	kernel.dispatch(FuncRequest(lfun, ss.str()));
 }
Index: src/Paragraph.cpp
===================================================================
--- src/Paragraph.cpp	(révision 18972)
+++ src/Paragraph.cpp	(copie de travail)
@@ -60,8 +60,8 @@
 
 using std::distance;
 using std::endl;
-using std::string;
 using std::ostream;
+using std::string;
 
 namespace lyx {
 
@@ -204,6 +204,9 @@ public:
 		      Layout const & layout) const;
 
 	///
+	void checkAuthors(AuthorActive & author_active);
+
+	///
 	unsigned int id_;
 	///
 	static unsigned int paragraph_id;
@@ -1025,6 +1028,12 @@ void Paragraph::Pimpl::validate(LaTeXFea
 }
 
 
+void Paragraph::Pimpl::checkAuthors(AuthorActive & author_active)
+{
+	changes_.checkAuthors(author_active);
+}
+
+
 } // namespace lyx
 
 
@@ -2670,4 +2679,11 @@ int Paragraph::checkBiblio(bool track_ch
 	return 1;
 }
 
+
+void Paragraph::checkAuthors(AuthorActive & author_active)
+{
+	pimpl_->checkAuthors(author_active);
+}
+
+
 } // namespace lyx
Index: src/Changes.h
===================================================================
--- src/Changes.h	(révision 18972)
+++ src/Changes.h	(copie de travail)
@@ -18,6 +18,7 @@
 #include "support/docstream.h"
 #include "support/lyxtime.h"
 
+#include <map>
 #include <vector>
 
 
@@ -51,6 +52,9 @@ bool operator!=(Change const & l, Change
 
 class BufferParams;
 
+class AuthorActive : public std::map<int, bool> {};
+
+
 class Changes {
 public:
 	/// set the pos to the given change
@@ -85,6 +89,9 @@ public:
 	static void lyxMarkChange(std::ostream & os, int & column,
 		Change const & old, Change const & change);
 
+	///
+	void Changes::checkAuthors(AuthorActive & author_active);
+
 private:
 	class Range {
 	public:
Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp	(révision 18972)
+++ src/Buffer.cpp	(copie de travail)
@@ -846,9 +846,12 @@ bool Buffer::write(ostream & ofs) const
 	    << "\\lyxformat " << LYX_FORMAT << "\n"
 	    << "\\begin_document\n";
 
+	AuthorActive author_active;
+	checkAuthors(*this, author_active);
+
 	// now write out the buffer parameters.
 	ofs << "\\begin_header\n";
-	params().writeFile(ofs);
+	params().writeFile(ofs, author_active);
 	ofs << "\\end_header\n";
 
 	// write the text
Index: src/Paragraph.h
===================================================================
--- src/Paragraph.h	(révision 18972)
+++ src/Paragraph.h	(copie de travail)
@@ -368,6 +368,10 @@ public:
 	/// was previously past that position. Return 0 otherwise.
 	int checkBiblio(bool track_changes);
 
+	/// For each author, sets author_active to true if there is a change
+	/// by this author in the paragraph.
+	void checkAuthors(AuthorActive & author_active);
+
 public:
 	///
 	InsetList insetlist;
Index: src/BufferParams.cpp
===================================================================
--- src/BufferParams.cpp	(révision 18972)
+++ src/BufferParams.cpp	(copie de travail)
@@ -641,7 +641,7 @@ string const BufferParams::readToken(Lex
 }
 
 
-void BufferParams::writeFile(ostream & os) const
+void BufferParams::writeFile(ostream & os, AuthorActive & author_active) const
 {
 	// The top of the file is written by the buffer.
 	// Prints out the buffer info into the .lyx file given by file
@@ -766,7 +766,10 @@ void BufferParams::writeFile(ostream & o
 	AuthorList::Authors::const_iterator a_it = pimpl_->authorlist.begin();
 	AuthorList::Authors::const_iterator a_end = pimpl_->authorlist.end();
 	for (; a_it != a_end; ++a_it) {
-		os << "\\author " << a_it->second << "\n";
+		if (author_active.find(a_it->first) != author_active.end())
+			os << "\\author " << a_it->second << "\n";
+		else
+			os << "\\author " << Author() << "\n";
 	}
 }
 

Reply via email to