Release v0.6.37: isolate image capture and OCR, fingerprint history duplicates
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "richtext.h"
|
||||
#include "storage.h"
|
||||
#include "diagnostics.h"
|
||||
#include "json.hpp"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
@@ -635,6 +636,55 @@ int main(int argc, char **argv)
|
||||
"Snipping Tool republish retains one pinned history entry");
|
||||
history.add(changedImage, L"SnippingTool", defaults);
|
||||
require(history.entries().size() == 2, "a new screenshot is retained");
|
||||
auto copiedText = ks::textClip(L"text after screenshot");
|
||||
history.add(copiedText, L"Editor", defaults);
|
||||
history.add(copiedText, L"Editor", defaults);
|
||||
require(history.entries().size() == 3 && !history.entries().front().image,
|
||||
"text after screenshot is retained and consecutive text duplicates are skipped");
|
||||
history.add(changedImage, L"SnippingTool", defaults);
|
||||
history.add(changedImage, L"SnippingTool", defaults);
|
||||
require(history.entries().size() == 4 && history.entries().front().image,
|
||||
"image after text is retained and consecutive image duplicates are skipped");
|
||||
history.add(withText, L"Editor", defaults);
|
||||
require(history.entries().size() == 5,
|
||||
"mixed image and text payload is not discarded by metadata prefilter");
|
||||
}
|
||||
{
|
||||
auto folder = temp / L"fingerprints";
|
||||
ks::Settings defaults;
|
||||
ks::History history(folder);
|
||||
history.add(firstImage, L"test", defaults);
|
||||
auto id = history.entries().front().id;
|
||||
history.pin(id);
|
||||
history.saveOcr(id, L"retained OCR", defaults);
|
||||
ks::History reopened(folder);
|
||||
require(reopened.entries().front().contentHash.size() == 64,
|
||||
"SHA-256 fingerprint survives encrypted index reload");
|
||||
// Deny payload reads: duplicates must still be detected using only the index.
|
||||
auto handle = CreateFileW((folder / (id + L".dat")).c_str(), GENERIC_READ, 0, nullptr,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
require(handle != INVALID_HANDLE_VALUE, "lock image payload for no-read regression");
|
||||
reopened.add(firstImage, L"test", defaults);
|
||||
reopened.add(secondImage, L"test", defaults);
|
||||
reopened.add(recoded, L"test", defaults);
|
||||
CloseHandle(handle);
|
||||
require(reopened.entries().size() == 1 && reopened.entries().front().pinned &&
|
||||
reopened.ocrText(id) == std::optional<std::wstring>(L"retained OCR"),
|
||||
"exact, OLE and pixel-equivalent duplicates need no payload read and retain pin/OCR");
|
||||
auto index = nlohmann::json::parse(ks::unprotect(ks::readFile(folder / L"index.dat", 1024*1024)));
|
||||
for (auto &entry : index)
|
||||
for (auto key : {"fingerprintVersion", "contentHash", "imageHash", "pixelHash"}) entry.erase(key);
|
||||
auto legacy = index.dump();
|
||||
ks::atomicWrite(folder / L"index.dat", ks::protect(ks::Bytes(legacy.begin(), legacy.end())));
|
||||
ks::History migrated(folder);
|
||||
migrated.add(secondImage, L"test", defaults);
|
||||
ks::History persisted(folder);
|
||||
require(persisted.entries().size() == 1 && persisted.entries().front().contentHash.size() == 64,
|
||||
"legacy duplicate migrates fingerprints without adding or losing an entry");
|
||||
persisted.add(changedImage, L"test", defaults);
|
||||
require(persisted.entries().size() == 2, "pixel fingerprint preserves genuinely changed images");
|
||||
persisted.add(firstImage, L"test", defaults);
|
||||
require(persisted.entries().size() == 3, "hash deduplication remains consecutive rather than global");
|
||||
}
|
||||
ks::Settings settings;
|
||||
settings.writeLog = false;
|
||||
|
||||
Reference in New Issue
Block a user