Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,37 @@ This repository currently targets `.NET 10` and includes the WinForms Configurat

Bentley Configuration Explorer was migrated to .NET 10 and dropped usage of the insecure BinaryFormatter. Any binary configuration files (*.bcf) from old versions need to be re-created from the workspace files going forward.

JSON workspace files use an explicit allowlist of persisted model and collection types. Unknown `$type` metadata is rejected without resolving or loading the named assembly. Object references are preserved for compatibility with existing JSON `.bcf` files, and JSON nesting is limited to 128 levels. Do not open untrusted `.bcf` files with older builds that lack this restriction.

Saved file graphs are validated before activation and before File History renders them. Child relationships must form a forest with unique ownership, consistent depths, at most 10,000 files, and at most 64 child levels. Normal parent/workspace back-references remain supported. Include processing uses the same file-count/depth limits and stops active include cycles using normalized, case-insensitive paths. Files may still be included again after their earlier processing completes. Limit failures record an error and abort processing.

Reload reads product metadata from embedded string resources using a data-only PE reader. It never loads the product DLL or invokes its code, even when the workspace supplies the executable path. Non-string resources are not deserialized. Missing or invalid DLLs are skipped; product metadata implemented only by computed getters is no longer evaluated.

"Open in Editor" tries Notepad++, Visual Studio Code, then Windows Notepad. Only executable paths in their standard Program Files or per-user Programs installation directories are considered; Notepad is located in the Windows system directory. Editor lookup never uses `PATH` or the current directory. Files are passed as separate arguments to the editor, never launched through file associations or executed directly. Nonstandard or portable editor installations are not automatically discovered.

Spreadsheet XML exports encode cell values, column headers, and worksheet names as literal text/attributes. Workspace values cannot add spreadsheet markup or formula attributes.

## Build requirements

- Visual Studio with .NET 10 SDK and Windows desktop development tools

## Persistence regression checks

From a Visual Studio Developer PowerShell, build and run the dependency-free regression runner against the real application:

```powershell
msbuild tests/WorkspacePersistence/WorkspacePersistence.csproj /restore /p:Configuration=Debug /p:Platform=x64
dotnet tests/WorkspacePersistence/bin/x64/Debug/net10.0-windows/WorkspacePersistence.dll
```

An optional argument supplies a malicious `.bcf` fixture to verify rejection. Run malicious fixtures only against the patched build. The checks cover existing-format compatibility, save/load round-trips, shared and circular references, unauthorized types at all three ArrayList entry points, assembly spoofing, and excessive nesting.

Reload checks also use a temporary product DLL with a marker-writing initializer to verify that opening and reprocessing a saved workspace reads string metadata without loading or executing that DLL. Non-string resources, short versions, missing/corrupt images, and the public metadata accessors are covered as well.

Editor checks inspect launch commands without opening editor windows, including line arguments, executable-looking filenames, and lookalike editor executables in an untrusted current directory and `PATH`.

Additional checks cover child-file cycles, shared-child amplification, actual reference-graph depth, file-count limits, XML/formula injection in both spreadsheet exporters, and real parser processing of self-includes, mutual cycles, deep include chains, and legitimate repeated includes. No Excel application is launched.

## Recommended project direction

The recommended future split is:
Expand Down
27 changes: 26 additions & 1 deletion WorkspaceCFG.sln
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.7.11925.98
Expand All @@ -10,26 +10,51 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0AB3BF05-4346-4AA6-1389-037BE0695223}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkspacePersistence", "tests\WorkspacePersistence\WorkspacePersistence.csproj", "{14624ADD-507F-412C-A7AF-DE1993A8C841}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Debug|Any CPU.ActiveCfg = Debug|x64
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Debug|Any CPU.Build.0 = Debug|x64
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Debug|x64.ActiveCfg = Debug|x64
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Debug|x64.Build.0 = Debug|x64
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Debug|x86.Build.0 = Debug|Any CPU
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Release|Any CPU.ActiveCfg = Release|x64
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Release|Any CPU.Build.0 = Release|x64
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Release|x64.ActiveCfg = Release|x64
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Release|x64.Build.0 = Release|x64
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Release|x86.ActiveCfg = Release|Any CPU
{D6AEB0D2-FCAC-0DA5-0398-811207F078F8}.Release|x86.Build.0 = Release|Any CPU
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Debug|Any CPU.ActiveCfg = Debug|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Debug|Any CPU.Build.0 = Debug|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Debug|x64.ActiveCfg = Debug|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Debug|x64.Build.0 = Debug|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Debug|x86.ActiveCfg = Debug|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Debug|x86.Build.0 = Debug|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Release|Any CPU.ActiveCfg = Release|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Release|Any CPU.Build.0 = Release|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Release|x64.ActiveCfg = Release|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Release|x64.Build.0 = Release|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Release|x86.ActiveCfg = Release|x64
{14624ADD-507F-412C-A7AF-DE1993A8C841}.Release|x86.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{14624ADD-507F-412C-A7AF-DE1993A8C841} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0C06F610-419D-4EB9-BF92-9780FE09A2FF}
EndGlobalSection
Expand Down
Loading
Loading