From ce60ef528952112adb7eb76c740da8c561632921 Mon Sep 17 00:00:00 2001 From: Kamil Marczak Date: Thu, 8 Oct 2026 14:53:24 +0200 Subject: [PATCH 1/3] fix(app): convert Windows paths in libanalyse and cracklib file access libanalyse writes cipher results with ofstream and cracklib opens its dictionary with fopen, both on paths CrypTool passes in Windows form. They were built without mfcwx, so files landed under names like "\var\folders\...\cry6.txt" in the working directory and the next read crashed on a NULL FILE* (Caesar encryption, among others). Both libraries are now compiled with mfcwx's fopen/fstream; their unit tests link stubs. Also adds MFCWX_AUTOMATION, a small script runner (menu commands, dialog buttons, control text, waits, snapshots) for reproducing UI flows. --- CMakeLists.txt | 13 ++++ port/mfcwx/include/mfcwx/pathcompat.h | 17 +++++ port/mfcwx/src/snapshot.cpp | 103 ++++++++++++++++++++++++++ port/mfcwx/tests/path_stubs.cpp | 12 +++ 4 files changed, 145 insertions(+) create mode 100644 port/mfcwx/include/mfcwx/pathcompat.h create mode 100644 port/mfcwx/tests/path_stubs.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3810ed60..5033985c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,19 @@ if(TARGET secude_compat) set_property(TARGET secude_compat PROPERTY INTERFACE_COMPILE_FEATURES "") endif() add_subdirectory(port/mfcwx) +# These libraries open files by paths CrypTool passes in Windows form; the app links mfcwx, which +# converts them, and the library tests use plain stubs. +foreach(target cryptool_analyse cryptool_cracklib) + target_compile_options(${target} PRIVATE "SHELL:-iquote ${CMAKE_SOURCE_DIR}/port/mfcwx/include" + "SHELL:-include ${CMAKE_SOURCE_DIR}/port/mfcwx/include/mfcwx/pathcompat.h") +endforeach() +add_library(mfcwx_path_stubs STATIC port/mfcwx/tests/path_stubs.cpp) +target_include_directories(mfcwx_path_stubs PRIVATE port/mfcwx/include) +foreach(test test_analyse test_cracklib) + if(TARGET ${test}) + target_link_libraries(${test} PRIVATE mfcwx_path_stubs) + endif() +endforeach() add_subdirectory(port/app) option(CRYPTOOL_DIALOG_GALLERY "Build the dialog snapshot tool" OFF) diff --git a/port/mfcwx/include/mfcwx/pathcompat.h b/port/mfcwx/include/mfcwx/pathcompat.h new file mode 100644 index 00000000..5422a201 --- /dev/null +++ b/port/mfcwx/include/mfcwx/pathcompat.h @@ -0,0 +1,17 @@ +#pragma once + +// Force-included into third-party libraries that open files by paths coming from CrypTool, +// which are in Windows form ("\dir\file"). + +#include + +#ifdef __cplusplus +extern "C" { +#endif +FILE* mfcwx_fopen(const char* name, const char* mode); +#ifdef __cplusplus +} +#include "mfcwx/fstreamcompat.h" +#endif + +#define fopen mfcwx_fopen diff --git a/port/mfcwx/src/snapshot.cpp b/port/mfcwx/src/snapshot.cpp index 88656884..68559456 100644 --- a/port/mfcwx/src/snapshot.cpp +++ b/port/mfcwx/src/snapshot.cpp @@ -7,6 +7,9 @@ #include #include +#include +#include +#include namespace mfcwx { @@ -78,9 +81,109 @@ class SnapshotTimer : public wxTimer { int m_round = 0; }; +std::string SafeName(const wxString& title) { + std::string name; + for (wxUniChar c : title) + name += (c.IsAscii() && isalnum(static_cast(c.GetValue()))) ? static_cast(c.GetValue()) : '_'; + return name.substr(0, 40); +} + +wxWindow* ActiveDialog() { + wxWindow* found = nullptr; + for (wxWindow* w : wxTopLevelWindows) { + auto* d = wxDynamicCast(w, wxDialog); + if (d && d->IsShown()) + found = d; + } + return found; +} + +// Development aid: MFCWX_AUTOMATION=file runs one step per line on a timer, for UI tests: +// command WM_COMMAND to the main window +// button WM_COMMAND (BN_CLICKED) to the topmost dialog +// text sets the text of a control of the topmost dialog +// wait +// snapshot