Verify partial node reads and reject malformed address rows
This commit is contained in:
1 parent
30a205340a
commit
44f6d8a5bc
2 files changed
+19
-4
No files matched your search
@@ -131,13 +131,13 @@ void NodesPage::refreshNodes() {
|
||||
const char* stage = "prepare";
|
||||
QString failure;
|
||||
sqlite3_stmt* st = nullptr;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONFIG, "Nodes refresh begin db=%p", static_cast<void*>(d));
|
||||
int rc = sqlite3_prepare_v2(d,
|
||||
"SELECT n.node_id,n.name,n.x25519_pubkey,n.ed25519_pubkey,n.last_seen_at,n.created_at,"
|
||||
" a.node_id,a.family,a.protocol,a.address,a.port,a.rtt,a.nat_mapping,a.nat_inbound,a.nat_source"
|
||||
" FROM nodes n LEFT JOIN node_addresses a ON a.node_id=n.node_id ORDER BY n.node_id,a.family,a.port",
|
||||
-1, &st, nullptr);
|
||||
std::unique_ptr<sqlite3_stmt, decltype(&sqlite3_finalize)> statement(st, sqlite3_finalize);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONFIG, "Nodes refresh begin db=%p", static_cast<void*>(d));
|
||||
if (rc == SQLITE_OK) {
|
||||
stage = "step";
|
||||
while ((rc = sqlite3_step(st)) == SQLITE_ROW) {
|
||||
@@ -187,7 +187,7 @@ void NodesPage::refreshNodes() {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Nodes refresh failed stage=%s rc=%d finalize=%d node=%016llx: %s",
|
||||
stage, rc, finalized, static_cast<unsigned long long>(currentNode), qPrintable(failure));
|
||||
m_table->setRowCount(0);
|
||||
m_dumpText->setPlainText(QCoreApplication::translate("ChatGui", "Query error") + ": " + failure);
|
||||
m_dumpText->setPlainText(QCoreApplication::translate("ChatGui", "Query error"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,14 +122,29 @@ private slots:
|
||||
}, &state), SQLITE_OK);
|
||||
sqlite3_progress_handler(db.handle, 1, [](void* context) {
|
||||
auto* state = static_cast<InterruptState*>(context);
|
||||
if (state->afterRow && !state->rows) return 0;
|
||||
if (state->afterRow && state->rows < 2) return 0;
|
||||
state->interrupted = true; return 1;
|
||||
}, &state);
|
||||
page.refreshNodes(); QVERIFY(state.interrupted); if (afterRow) QVERIFY(state.rows > 0);
|
||||
page.refreshNodes(); QVERIFY(state.interrupted); if (afterRow) QVERIFY(state.rows >= 2);
|
||||
checkFailure(page); QVERIFY(!sqlite3_next_stmt(db.handle, nullptr));
|
||||
sqlite3_progress_handler(db.handle, 0, nullptr, nullptr); sqlite3_trace_v2(db.handle, 0, nullptr, nullptr);
|
||||
page.refreshNodes(); checkSnapshot(page);
|
||||
}
|
||||
void invalidAddress_data() {
|
||||
QTest::addColumn<QByteArray>("update");
|
||||
QTest::newRow("unknown-family") << QByteArray("family=7");
|
||||
QTest::newRow("empty-blob") << QByteArray("address=x''");
|
||||
QTest::newRow("text-instead-of-blob") << QByteArray("address='addr'");
|
||||
}
|
||||
void invalidAddress() {
|
||||
QFETCH(QByteArray, update);
|
||||
NodesDatabase db; QVERIFY(db.open()); NodesPage page(&db.manager);
|
||||
page.refreshNodes(); checkSnapshot(page);
|
||||
QVERIFY(db.execute(("UPDATE node_addresses SET " + update + " WHERE family=4").constData()));
|
||||
page.refreshNodes(); checkFailure(page); QVERIFY(!sqlite3_next_stmt(db.handle, nullptr));
|
||||
QVERIFY(db.execute("UPDATE node_addresses SET family=4,address=x'7F000001' WHERE protocol=1"));
|
||||
page.refreshNodes(); checkSnapshot(page);
|
||||
}
|
||||
void disconnectedDatabase() {
|
||||
NodesDatabase db; QVERIFY(db.open()); NodesPage page(&db.manager);
|
||||
page.refreshNodes(); checkSnapshot(page); db.manager.setDb(nullptr); page.refreshNodes();
|
||||
|
||||
Reference in new issue
Block a user