- added global extended header (introducing global file format version
4) - unknown extended headers will not be just ignored anymore, they will be read and written again when saving the file
This commit is contained in:
parent
a6a089d765
commit
b860d01b1e
23
io/entry.cpp
23
io/entry.cpp
|
@ -223,7 +223,7 @@ NodeEntry::NodeEntry(istream &stream) :
|
|||
m_expandedByDefault = flags & 0x80;
|
||||
extendedHeaderSize -= 1;
|
||||
}
|
||||
stream.seekg(extendedHeaderSize, ios_base::cur);
|
||||
m_extendedData = reader.readString(extendedHeaderSize);
|
||||
}
|
||||
uint32 childCount = reader.readUInt32BE();
|
||||
for(uint32 i = 0; i < childCount; ++i) {
|
||||
|
@ -345,11 +345,16 @@ Entry *NodeEntry::entryByPath(list<string> &path, bool includeThis, EntryType *c
|
|||
void NodeEntry::make(ostream &stream) const
|
||||
{
|
||||
BinaryWriter writer(&stream);
|
||||
writer.writeByte(isExpandedByDefault() ? 0x0 : 0x1); // version
|
||||
writer.writeByte(isExpandedByDefault() && m_extendedData.empty() ? 0x0 : 0x1); // version
|
||||
writer.writeLengthPrefixedString(label());
|
||||
if(!isExpandedByDefault()) {
|
||||
writer.writeUInt16BE(1); // extended header is 1 byte long
|
||||
writer.writeByte(0x00); // all flags cleared
|
||||
if(!isExpandedByDefault() || !m_extendedData.empty()) {
|
||||
writer.writeUInt16BE(1 + m_extendedData.size()); // extended header is 1 byte long
|
||||
byte flags = 0x00;
|
||||
if(isExpandedByDefault()) {
|
||||
flags |= 0x80;
|
||||
}
|
||||
writer.writeByte(flags);
|
||||
writer.writeString(m_extendedData);
|
||||
}
|
||||
writer.writeUInt32BE(m_children.size());
|
||||
for(const Entry *child : m_children) {
|
||||
|
@ -391,7 +396,7 @@ AccountEntry::AccountEntry(istream &stream)
|
|||
if(version == 0x1) { // version 0x1 has an extended header
|
||||
uint16 extendedHeaderSize = reader.readUInt16BE();
|
||||
// currently there's nothing to read here
|
||||
stream.seekg(extendedHeaderSize, ios_base::cur);
|
||||
m_extendedData = reader.readString(extendedHeaderSize);
|
||||
}
|
||||
uint32 fieldCount = reader.readUInt32BE();
|
||||
for(uint32 i = 0; i < fieldCount; ++i) {
|
||||
|
@ -425,8 +430,12 @@ AccountEntry::~AccountEntry()
|
|||
void AccountEntry::make(ostream &stream) const
|
||||
{
|
||||
BinaryWriter writer(&stream);
|
||||
writer.writeByte(0x80 | 0x0); // version
|
||||
writer.writeByte(0x80 | (m_extendedData.empty() ? 0x0 : 0x1)); // version
|
||||
writer.writeLengthPrefixedString(label());
|
||||
if(!m_extendedData.empty()) {
|
||||
writer.writeUInt16BE(m_extendedData.size());
|
||||
writer.writeString(m_extendedData);
|
||||
}
|
||||
writer.writeUInt32BE(m_fields.size());
|
||||
for(const Field &field : m_fields) {
|
||||
field.make(stream);
|
||||
|
|
|
@ -53,6 +53,10 @@ private:
|
|||
std::string m_label;
|
||||
NodeEntry *m_parent;
|
||||
int m_index;
|
||||
|
||||
protected:
|
||||
std::string m_extendedData;
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -110,6 +114,7 @@ public:
|
|||
void setExpandedByDefault(bool expandedByDefault);
|
||||
virtual void make(std::ostream &stream) const;
|
||||
virtual NodeEntry *clone() const;
|
||||
|
||||
private:
|
||||
std::vector<Entry *> m_children;
|
||||
bool m_expandedByDefault;
|
||||
|
|
|
@ -48,7 +48,7 @@ Field::Field(AccountEntry *tiedAccount, istream &stream)
|
|||
if(version == 0x1) { // version 0x1 has an extended header
|
||||
uint16 extendedHeaderSize = reader.readUInt16BE();
|
||||
// currently there's nothing to read here
|
||||
stream.seekg(extendedHeaderSize, ios_base::cur);
|
||||
m_extendedData = reader.readString(extendedHeaderSize);
|
||||
}
|
||||
m_tiedAccount = tiedAccount;
|
||||
} else {
|
||||
|
@ -62,10 +62,14 @@ Field::Field(AccountEntry *tiedAccount, istream &stream)
|
|||
void Field::make(ostream &stream) const
|
||||
{
|
||||
BinaryWriter writer(&stream);
|
||||
writer.writeByte(0x0); // version
|
||||
writer.writeByte(m_extendedData.empty() ? 0x0 : 0x1); // version
|
||||
writer.writeLengthPrefixedString(m_name);
|
||||
writer.writeLengthPrefixedString(m_value);
|
||||
writer.writeByte(static_cast<byte>(m_type));
|
||||
if(!m_extendedData.empty()) {
|
||||
writer.writeUInt16BE(m_extendedData.size());
|
||||
writer.writeString(m_extendedData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,10 @@ private:
|
|||
std::string m_value;
|
||||
FieldType m_type;
|
||||
AccountEntry *m_tiedAccount;
|
||||
|
||||
protected:
|
||||
std::string m_extendedData;
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -135,8 +135,9 @@ void PasswordFile::load()
|
|||
}
|
||||
// check version and flags (used in version 0x3 only)
|
||||
uint32 version = m_freader.readUInt32LE();
|
||||
if(version != 0x0U && version != 0x1U && version != 0x2U && version != 0x3U)
|
||||
if(version != 0x0U && version != 0x1U && version != 0x2U && version != 0x3U && version != 0x4U) {
|
||||
throw ParsingException("Version is unknown.");
|
||||
}
|
||||
bool decrypterUsed;
|
||||
bool ivUsed;
|
||||
bool compressionUsed;
|
||||
|
@ -150,6 +151,13 @@ void PasswordFile::load()
|
|||
ivUsed = version == 0x2U;
|
||||
compressionUsed = false;
|
||||
}
|
||||
// skip extended header
|
||||
// the extended header might be used in further versions to
|
||||
// add additional information without breaking compatibility
|
||||
if(version == 0x4U) {
|
||||
uint16 extendedHeaderSize = m_freader.readUInt16BE();
|
||||
m_extendedHeader = m_freader.readString(extendedHeaderSize);
|
||||
}
|
||||
// get length
|
||||
fstream::pos_type headerSize = m_file.tellg();
|
||||
m_file.seekg(0, ios_base::end);
|
||||
|
@ -250,8 +258,7 @@ void PasswordFile::save(bool useEncryption, bool useCompression)
|
|||
m_file.open(m_path, ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary);
|
||||
// write header
|
||||
m_fwriter.writeUInt32LE(0x7770616DU); // write magic number
|
||||
//m_fwriter.writeUInt32(useEncryption ? 2U : 0U); // write version (old versions)
|
||||
m_fwriter.writeUInt32LE(0x3U); // write version
|
||||
m_fwriter.writeUInt32LE(m_extendedHeader.empty() ? 0x3U : 0x4U); // write version, extended header requires version 4
|
||||
byte flags = 0x00;
|
||||
if(useEncryption) {
|
||||
flags |= 0x80 | 0x40;
|
||||
|
@ -260,6 +267,11 @@ void PasswordFile::save(bool useEncryption, bool useCompression)
|
|||
flags |= 0x20;
|
||||
}
|
||||
m_fwriter.writeByte(flags);
|
||||
// write extened header
|
||||
if(!m_extendedHeader.empty()) {
|
||||
m_fwriter.writeUInt16BE(m_extendedHeader.size());
|
||||
m_fwriter.writeString(m_extendedHeader);
|
||||
}
|
||||
// serialize root entry and descendants
|
||||
stringstream buffstr(stringstream::in | stringstream::out | stringstream::binary);
|
||||
buffstr.exceptions(ios_base::failbit | ios_base::badbit);
|
||||
|
|
|
@ -46,6 +46,7 @@ private:
|
|||
std::string m_path;
|
||||
char m_password[32];
|
||||
std::unique_ptr<NodeEntry> m_rootEntry;
|
||||
std::string m_extendedHeader;
|
||||
std::fstream m_file;
|
||||
IoUtilities::BinaryReader m_freader;
|
||||
IoUtilities::BinaryWriter m_fwriter;
|
||||
|
|
Loading…
Reference in New Issue