FS#13972 - Fix crash creating voice files under Windows (Alessio Lenzi)

VoiceFileCreator::createVoiceFile() stored corrFile as the address of a
local QTemporaryFile (or a local QFile used as fallback). Both objects
were destroyed before VoiceFileCreator::create() called
TalkGenerator::setLang(), leaving a dangling pointer.

On Windows this produced an access violation in RockboxUtility.exe
immediately after the voice strings had been read. Windows reported
exception 0xc0000005.

The change gives the corrections file QObject lifetime under
VoiceFileCreator, uses the built-in corrections file as a persistent
default, and replaces it with a persistent extracted QTemporaryFile when
extraction succeeds.

Change-Id: I29a371d2431021833676dec2b875186a3c021b13
This commit is contained in:
Solomon Peachy 2026-08-04 16:28:39 -04:00
parent b4db6ffbff
commit 1b6767a7d7

View file

@ -28,6 +28,7 @@
VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent)
{
m_wavtrimThreshold=500;
corrFile = nullptr;
}
void VoiceFileCreator::abort()
@ -40,6 +41,11 @@ bool VoiceFileCreator::createVoiceFile()
{
m_talkList.clear();
m_abort = false;
delete corrFile;
corrFile = new QFile(":/builtin/voice-corrections.txt", this);
corrFile->open(QIODevice::ReadOnly);
emit logItem(tr("Starting Voicefile generation"),LOGINFO);
// test if tempdir exists
@ -88,19 +94,17 @@ bool VoiceFileCreator::createVoiceFile()
}
if(cindex != -1) {
LOG_INFO() << "extracting voice corrections file";
QTemporaryFile corrfileT;
corrfileT.open();
QString cfn = corrfileT.fileName();
QTemporaryFile *corrfileT = new QTemporaryFile(this);
corrfileT->open();
QString cfn = corrfileT->fileName();
if(z.extractArchive(cfn, QFileInfo(contents.at(cindex)).fileName())) {
emit logItem(tr("Extracted voice corrections file from installation"), LOGINFO);
corrFile = &corrfileT;
delete corrFile;
corrFile = corrfileT;
} else {
// XXX try to fetch an updated file via voicecorrections_url ?
corrfileT.close();
delete corrfileT;
emit logItem(tr("Using internal voice corrections file"), LOGINFO);
QFile corrfile(":/builtin/voice-corrections.txt");
corrfile.open(QIODevice::ReadOnly);
corrFile = &corrfile;
}
}
if(eindex != -1) {
@ -182,7 +186,7 @@ bool VoiceFileCreator::createVoiceFile()
// everything successful, now create the actual voice file.
create();
if (corrFile->isOpen())
if (corrFile && corrFile->isOpen())
corrFile->close();
return true;
}
@ -326,7 +330,7 @@ void VoiceFileCreator::create(void)
{
TalkGenerator generator(this);
// set language for string correction. If not set no correction will be made.
if(useCorrection)
if(useCorrection && corrFile)
generator.setLang(m_lang, corrFile);
connect(&generator, &TalkGenerator::done, this, &VoiceFileCreator::done);
connect(&generator, &TalkGenerator::logItem, this, &VoiceFileCreator::logItem);