1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-01 08:29:27 +02:00

Don't destroy auto-save file written by different architecture...

... the error checking might not be complete, but it is sufficient for the
observed cases, where switching between 32 and 64 bit Mac builds causes
auto-recovery in one build to destroy the data saved by the other build.

Now instead, you will see an error message, recommending that you run the
same version of Audacity that produced the file.

Note that decoding of autosave files can also (less commonly) happen with
a command-line argument, and a message is written to standard out.  Give the
same message in that case.

Localization of this changed message unfortunately can't happen this late in
2.3.2 development.
This commit is contained in:
Paul Licameli 2019-04-28 20:51:24 -04:00 committed by James Crook
parent c8d95e1117
commit 2ba17c78d6
4 changed files with 41 additions and 14 deletions

View File

@ -1520,7 +1520,7 @@ bool AudacityApp::OnInit()
} }
else else
{ {
wxPrintf(_("Decoding failed\n")); wxPrintf( AutoSaveFile::FailureMessage( fileName ) );
} }
exit(1); exit(1);
} }

View File

@ -484,6 +484,16 @@ enum FieldTypes
FT_Name // type, ID, name length, name FT_Name // type, ID, name length, name
}; };
wxString AutoSaveFile::FailureMessage( const FilePath &filePath )
{
return wxString::Format(
_("Could not decode crash recovery file: %s\n\n\
This file was saved by a version of Audacity built for a different processor architecture. \
Try running that version of Audacity to recover its contents."),
filePath
);
}
AutoSaveFile::AutoSaveFile(size_t allocSize) AutoSaveFile::AutoSaveFile(size_t allocSize)
{ {
mAllocSize = allocSize; mAllocSize = allocSize;
@ -766,9 +776,16 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
std::vector<IdMap> mIdStack; std::vector<IdMap> mIdStack;
mIds.clear(); mIds.clear();
struct Error{};
auto Lookup = [&mIds]( short id ) -> const wxString & {
auto iter = mIds.find( id );
if ( iter == mIds.end() )
throw Error{};
return iter->second;
};
while ( !in.Eof() ) try { while ( !in.Eof() ) {
{
short id; short id;
switch (in.GetC()) switch (in.GetC())
@ -804,7 +821,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
{ {
in.Read(&id, sizeof(id)); in.Read(&id, sizeof(id));
out.StartTag(mIds[id]); out.StartTag(Lookup(id));
} }
break; break;
@ -812,7 +829,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
{ {
in.Read(&id, sizeof(id)); in.Read(&id, sizeof(id));
out.EndTag(mIds[id]); out.EndTag(Lookup(id));
} }
break; break;
@ -825,7 +842,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
WxChars val{ len / sizeof(wxChar) }; WxChars val{ len / sizeof(wxChar) };
in.Read(val.get(), len); in.Read(val.get(), len);
out.WriteAttr(mIds[id], wxString(val.get(), len / sizeof(wxChar))); out.WriteAttr(Lookup(id), wxString(val.get(), len / sizeof(wxChar)));
} }
break; break;
@ -838,7 +855,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
in.Read(&val, sizeof(val)); in.Read(&val, sizeof(val));
in.Read(&dig, sizeof(dig)); in.Read(&dig, sizeof(dig));
out.WriteAttr(mIds[id], val, dig); out.WriteAttr(Lookup(id), val, dig);
} }
break; break;
@ -851,7 +868,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
in.Read(&val, sizeof(val)); in.Read(&val, sizeof(val));
in.Read(&dig, sizeof(dig)); in.Read(&dig, sizeof(dig));
out.WriteAttr(mIds[id], val, dig); out.WriteAttr(Lookup(id), val, dig);
} }
break; break;
@ -862,7 +879,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
in.Read(&id, sizeof(id)); in.Read(&id, sizeof(id));
in.Read(&val, sizeof(val)); in.Read(&val, sizeof(val));
out.WriteAttr(mIds[id], val); out.WriteAttr(Lookup(id), val);
} }
break; break;
@ -873,7 +890,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
in.Read(&id, sizeof(id)); in.Read(&id, sizeof(id));
in.Read(&val, sizeof(val)); in.Read(&val, sizeof(val));
out.WriteAttr(mIds[id], val); out.WriteAttr(Lookup(id), val);
} }
break; break;
@ -884,7 +901,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
in.Read(&id, sizeof(id)); in.Read(&id, sizeof(id));
in.Read(&val, sizeof(val)); in.Read(&val, sizeof(val));
out.WriteAttr(mIds[id], val); out.WriteAttr(Lookup(id), val);
} }
break; break;
@ -895,7 +912,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
in.Read(&id, sizeof(id)); in.Read(&id, sizeof(id));
in.Read(&val, sizeof(val)); in.Read(&val, sizeof(val));
out.WriteAttr(mIds[id], val); out.WriteAttr(Lookup(id), val);
} }
break; break;
@ -906,7 +923,7 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
in.Read(&id, sizeof(id)); in.Read(&id, sizeof(id));
in.Read(&val, sizeof(val)); in.Read(&val, sizeof(val));
out.WriteAttr(mIds[id], val); out.WriteAttr(Lookup(id), val);
} }
break; break;
@ -938,6 +955,11 @@ bool AutoSaveFile::Decode(const FilePath & fileName)
wxASSERT(true); wxASSERT(true);
break; break;
} }
} }
catch( const Error & )
{
// return before committing, so we do not overwrite the recovery file!
return false;
} }
out.Commit(); out.Commit();

View File

@ -75,6 +75,8 @@ class AUDACITY_DLL_API AutoSaveFile final : public XMLWriter
{ {
public: public:
static wxString FailureMessage( const FilePath &filePath );
AutoSaveFile(size_t allocSize = 1024 * 1024); AutoSaveFile(size_t allocSize = 1024 * 1024);
virtual ~AutoSaveFile(); virtual ~AutoSaveFile();

View File

@ -3070,10 +3070,13 @@ void AudacityProject::OpenFile(const FilePath &fileNameArg, bool addtohistory)
AutoSaveFile asf; AutoSaveFile asf;
if (!asf.Decode(fileName)) if (!asf.Decode(fileName))
{ {
auto message = AutoSaveFile::FailureMessage( fileName );
AudacityMessageBox( AudacityMessageBox(
wxString::Format( _("Could not decode file: %s"), fileName ), message,
_("Error decoding file"), _("Error decoding file"),
wxOK | wxCENTRE, this); wxOK | wxCENTRE, this);
// Important: Prevent deleting any temporary files!
DirManager::SetDontDeleteTempFiles();
return; return;
} }
} }