mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-15 10:04:13 +02:00
Fix two faults the end-state gates found (stage D7)
A .qetz re-saved after opening from its index saved wrong folio numbers
in its database: reading each folio's header wrote its row with a
number counted from the folios read so far ("1/1", "2/2" for "1/3",
"2/3"), and an index-opened project keeps the rows it was saved with,
so nothing wrote them again. The folio table's rows are no longer
written while the project is being read (projectDataBase::
diagramInfoChanged()). Folio list tables showed it.
A .qetz whose project.sqlite is not a database crashed QElectroTech: the
first statement could not be prepared and SQLite was handed a null
statement. A statement that cannot be prepared now binds nothing and
steps to no row, and the file is refused.
Gates: 342 corpus projects,
written by QElectroTech 0.3 to 0.200, all open; .qet -> .qetz -> .qet
equals the plain resave with every folio built; a .qetz re-saved twice
holds the same bytes entry by entry but the save's own name, path and
time (the first fault made the first re-save differ); hostile .qetz
(truncated, garbage database, view for a table, trigger, escaping and
repeated names, later format, missing folio, 2 GiB zip bomb) neither
crash nor hang and none opens; an unknown extra entry still opens.
tst_lazyfolios: folio numbers with totals from the index as when built
(fails without the fix); tst_qetcontainer: garbage database refused
(segfaults without it). ctest 96/96 both ways; save and export gates
same on 342.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -149,7 +149,11 @@ class Statement
|
||||
}
|
||||
~Statement() { sqlite3_finalize(m_stmt); }
|
||||
bool ok() const { return m_stmt; }
|
||||
//A statement that could not be prepared (the database is not
|
||||
//one, a table is missing) binds nothing and steps to no row:
|
||||
//SQLite's own calls are not all safe on a null statement
|
||||
void bind(const QVariantList &values) {
|
||||
if (!m_stmt) return;
|
||||
sqlite3_reset(m_stmt);
|
||||
sqlite3_clear_bindings(m_stmt);
|
||||
for (int i = 0 ; i < values.size() ; ++i) {
|
||||
@@ -165,11 +169,13 @@ class Statement
|
||||
}
|
||||
}
|
||||
bool run(const QVariantList &values) {
|
||||
if (!m_stmt) return false;
|
||||
bind(values);
|
||||
return sqlite3_step(m_stmt) == SQLITE_DONE;
|
||||
}
|
||||
bool next() { return sqlite3_step(m_stmt) == SQLITE_ROW; }
|
||||
bool next() { return m_stmt && sqlite3_step(m_stmt) == SQLITE_ROW; }
|
||||
QVariant value(int column) const {
|
||||
if (!m_stmt) return QVariant();
|
||||
switch (sqlite3_column_type(m_stmt, column)) {
|
||||
case SQLITE_NULL: return QVariant();
|
||||
case SQLITE_INTEGER: return QVariant(sqlite3_column_int(m_stmt, column));
|
||||
|
||||
Reference in New Issue
Block a user