Free and open-source PDF editor for Windows with a built-in PDF 2.0 engine. View, annotate, OCR, merge, split, crop, rotate, compare, edit text, draw, sign, fill forms, print, flatten, and open password-protected PDFs without a subscription.
This report summarizes scanner evidence for SteveTheKiller/KillerPDF, a C# project with 4,078 GitHub stars. SynthScan examined 140,523 lines of code across 537 source files, recording 241 pattern matches distributed across 7 syntactic categories. The legacy adjusted pattern signal is 4.2 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 104 finding(s).
Are imports declared and package/API names verified? 6 finding(s).
Are wrappers, guards, and repeated structures necessary? 132 finding(s).
Which changes need focused human review? 241 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 241 distinct pattern matches across 7 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | App.xaml.cs | 46 | // ── Machine-wide install (all users), matching Killendar / KillerShell ───────────── | COMMENT |
| MEDIUM | App.xaml.cs | 1254 | // ── Recent files (most-recent first, capped) ───────────────────── | COMMENT |
| MEDIUM | App.xaml.cs | 1337 | // ── Root grid: title bar row + content row ────────────────── | COMMENT |
| MEDIUM | App.xaml.cs | 1342 | // ── Title bar ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | App.xaml.cs | 1405 | // ── Content ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | App.xaml.cs | 1491 | // ── WinVerifyTrust P/Invoke ────────────────────────────────────────── | COMMENT |
| MEDIUM | App.xaml.cs | 1527 | // ── Public helpers ─────────────────────────────────────────────────── | COMMENT |
| MEDIUM | App.xaml.cs | 1614 | // ── About dialog ──────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | App.xaml.cs | 1623 | // ── Layout ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | App.xaml.cs | 1813 | // ── Downgrade guard ──────────────────────────────────────────────────── | COMMENT |
| MEDIUM | MainWindow.xaml.cs | 41 | // ── Split pane ───────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Shell/PaneDrag.cs | 47 | // ── Drag feedback ─────────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Shell/KeyboardMapOverlay.cs | 33 | // ── Binding table ────────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Shell/KeyboardMapOverlay.cs | 41 | // ── Physical layout ──────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Shell/KeyboardMapOverlay.cs | 109 | // ── View toggle (LIST / KEYBOARD) ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Shell/KeyboardMapOverlay.cs | 131 | // ── Board construction (once, lazily) ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Shell/KeyboardMapOverlay.cs | 271 | // ── Caption marquee (hover a lit key whose caption is cut off) ───────────────────────── | COMMENT |
| MEDIUM | Shell/KeyboardMapOverlay.cs | 323 | // ── Layer painting ───────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Shell/SettingsPanel.cs | 706 | // ── Toolbar appearance (right-click picker on the bar) ──────────── | COMMENT |
| MEDIUM | Shell/SettingsPanel.cs | 1135 | // ── Responsive toolbar overflow ─────────────────────────────────── | COMMENT |
| MEDIUM | Shell/KeyboardShortcuts.cs | 583 | // ── Jump history (Alt+Left / Alt+Right / mouse back-forward buttons) ───────────────────── | COMMENT |
| MEDIUM | Features/Viewer/MainWindowViewerStubs.cs | 32 | // ── Annotations ────────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Features/Viewer/MainWindowViewerStubs.cs | 62 | // ── Page canvases ──────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Features/Viewer/MainWindowViewerStubs.cs | 67 | // ── Undo ───────────────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Features/Viewer/MainWindowViewerStubs.cs | 71 | // ── Text editing ───────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Features/Viewer/MainWindowViewerStubs.cs | 79 | // ── Text selection ─────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Features/Viewer/MainWindowViewerStubs.cs | 83 | // ── Crop ───────────────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Features/Viewer/MainWindowViewerStubs.cs | 89 | // ── Links ──────────────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Features/Viewer/MainWindowViewerStubs.cs | 98 | // ── Save paths ─────────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Features/Viewer/MainWindowViewerStubs.cs | 101 | // ── Bound from MainWindow.xaml - see the class comment, these are load-bearing ─────── | COMMENT |
| MEDIUM | Features/Viewer/MainWindowViewerBridge.cs | 30 | // ══ INWARD: chrome the viewer reads ═════════════════════════════════════════════════ | COMMENT |
| MEDIUM | Features/Viewer/MainWindowViewerBridge.cs | 41 | // ══ INWARD: per-document state (group B - goes when the viewer owns its session) ═════ | COMMENT |
| MEDIUM | Features/Viewer/MainWindowViewerBridge.cs | 55 | // ══ OUTWARD: the viewer's members, under the names the window already calls ══════════ | COMMENT |
| MEDIUM | Features/Viewer/IViewerHost.cs | 41 | // ── Chrome the viewer updates (group A) ───────────────────────────────────────────── | COMMENT |
| MEDIUM | Features/Viewer/IViewerHost.cs | 123 | // ── Notifications, so the window can update chrome for the FOCUSED viewer only ─────── | COMMENT |
| MEDIUM⚡ | Models/ViewerState.cs | 63 | // ── Zoom / fit ────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Models/ViewerState.cs | 72 | // ── In-flight render work ─────────────────────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | Models/ViewerState.cs | 81 | // ── Continuous-view bookkeeping ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | Models/ViewerState.cs | 93 | // ── Gesture routing ───────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Models/ViewerState.cs | 101 | // ── Visual hosts ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/ColorPickerDialog.cs | 64 | // ── UI ────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/ColorPickerDialog.cs | 213 | // ── Interaction ───────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/ColorPickerDialog.cs | 239 | // ── Eyedropper (desktop-wide) ─────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/ColorPickerDialog.cs | 292 | // ── Saved swatches ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/ColorPickerDialog.cs | 335 | // ── Small themed control builders ─────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/ColorPickerDialog.cs | 439 | // ── Color math / parsing ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 37 | // ── Win32-compatible surface ───────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 85 | // ── internals ──────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 112 | // ── Tree / pinned places / recents / hidden state ──────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 305 | // ── Filters ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 406 | // ── Quick places (pinned + drives) ─────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 600 | // ── Navigation ─────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 915 | // ── Recent locations ───────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 952 | // ── Hidden / dot files ─────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 1106 | // ── View modes ─────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 1170 | // ── Sorting ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FileDialog.xaml.cs | 1223 | // ── Accept / cancel ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | Controls/FolderTree.cs | 16 | // ═══════════════════════════════════════════════════════════ | COMMENT |
| MEDIUM | Controls/FolderTree.cs | 18 | // ═══════════════════════════════════════════════════════════ | COMMENT |
| MEDIUM | Controls/Viewer/PdfViewer.Bridge2.cs | 17 | // ── Selection ──────────────────────────────────────────────────────────────────────── | COMMENT |
| 71 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | App.xaml.cs | 1101 | COMMENT | |
| LOW | MainWindow.xaml.cs | 241 | private (bool Initials, int ObjNum, int Page, double X, double Y, double W, double H)? _pendingSignField; | COMMENT |
| LOW | MainWindow.xaml.cs | 321 | // so dropping onto an open document works too. The empty-state DropZone marks its own drop | COMMENT |
| LOW | Shell/SplitPane.cs | 41 | COMMENT | |
| LOW | Shell/SplitPane.cs | 81 | // The wheel focuses too. The zoom toolbar, the zoom box and Ctrl+wheel all act on the | COMMENT |
| LOW | Shell/SplitPane.cs | 261 | if (_restoringSplit) | COMMENT |
| LOW | Shell/SplitPane.cs | 341 | private System.Windows.Threading.DispatcherTimer? _splitAnim; | COMMENT |
| LOW | Shell/SplitPane.cs | 441 | PaneACol.Width = new GridLength(aStart, GridUnitType.Pixel); | COMMENT |
| LOW | Shell/AppScale.cs | 101 | // so the footer carries it while you are zooming and gives the line back a beat after | COMMENT |
| LOW | Shell/PaneDrag.cs | 1 | using System; | COMMENT |
| LOW | Shell/PaneDrag.cs | 21 | /// </summary> | COMMENT |
| LOW | Shell/PaneDrag.cs | 101 | { | COMMENT |
| LOW | Shell/SidebarLayout.cs | 81 | // on all four sides. | COMMENT |
| LOW | Shell/SidebarLayout.cs | 121 | // moves. Top and bottom stay 0: PaneShadow is Direction 270 and draws outside the element's | COMMENT |
| LOW | Shell/SettingsPanel.cs | 261 | COMMENT | |
| LOW | Shell/SettingsPanel.cs | 581 | // so rebuild it in the new language. (The sidebar menu is rebuilt on each open.) | COMMENT |
| LOW | Shell/ShortcutsOverlay.cs | 1 | using System.Linq; | COMMENT |
| LOW | Shell/ShortcutsOverlay.cs | 61 | .Replace("%zout%", Services.KeyLayout.ZoomOutChar()); | COMMENT |
| LOW | Shell/SystemMenu.cs | 1 | using System; | COMMENT |
| LOW | Shell/FileOperations.cs | 841 | KillerDialog.Show(this, Loc("Str_Err_MergeFailed") + "\n" + ex.Message, "KillerPDF", MessageBoxButton.OK | COMMENT |
| LOW | Shell/AnnotationBars.cs | 341 | public object ConvertBack(object value, Type t, object p, System.Globalization.CultureInfo c) => value; | COMMENT |
| LOW | Shell/FullScreen.cs | 121 | // bounds FIRST, then drop to Normal: WPF restores to the just-set bounds, so the window lands | COMMENT |
| LOW | Features/About/IAboutHost.cs | 1 | namespace KillerPDF.Features | COMMENT |
| LOW | Features/Cli/CliRunner.cs | 21 | // The scrubs, bitmap helpers, import helpers and PDFium interop all live in Services | COMMENT |
| LOW | Features/Cli/CliRunner.cs | 41 | // decrypt, the rotation-safe rasterizer, the OCR text-layer builder - so | COMMENT |
| LOW | Features/Cli/BatchRunner.cs | 21 | // Resaves through The KillerPDF.Engine's deterministic full-document writer. No window, | COMMENT |
| LOW | Features/Viewer/MainWindowViewerBridge.cs | 1 | using System.Collections.Generic; | COMMENT |
| LOW | Features/Viewer/MainWindowViewerBridge.cs | 21 | /// | COMMENT |
| LOW | Features/Viewer/MainWindowViewerBridge.cs | 41 | // ══ INWARD: per-document state (group B - goes when the viewer owns its session) ═════ | COMMENT |
| LOW | Features/Viewer/MainWindowViewerBridge.cs | 101 | private void ZoomOut_Click(object sender, RoutedEventArgs e) => ActiveViewer.ZoomOut_Click(sender, e); | COMMENT |
| LOW | Features/Viewer/IViewerHost.cs | 1 | using System.Windows; | COMMENT |
| LOW | Features/Viewer/IViewerHost.cs | 21 | /// That audit split the coupling into three groups, and only the first belongs here: | COMMENT |
| LOW | Features/Viewer/IViewerHost.cs | 41 | // ── Chrome the viewer updates (group A) ───────────────────────────────────────────── | COMMENT |
| LOW | Features/Viewer/MainWindowViewerElements.cs | 1 | using System.Windows.Controls; | COMMENT |
| LOW | Models/ViewTypes.cs | 1 | namespace KillerPDF | COMMENT |
| LOW | Models/UndoTypes.cs | 1 | using System.Collections.Generic; | COMMENT |
| LOW | Models/LinkTypes.cs | 1 | namespace KillerPDF | COMMENT |
| LOW | Models/ViewerState.cs | 1 | using System.Collections.Generic; | COMMENT |
| LOW | Models/ViewerState.cs | 21 | /// </summary> | COMMENT |
| LOW | Models/ViewerState.cs | 41 | /// which between them cover every write: | COMMENT |
| LOW | Models/ViewerState.cs | 101 | // ── Visual hosts ──────────────────────────────────────────────────────────────── | COMMENT |
| LOW | Controls/FlyoutPlacement.cs | 1 | using System.Windows; | COMMENT |
| LOW | Controls/FlyoutPlacement.cs | 21 | /// rail sat near the window's right edge; "Top" opened them over the status bar. Hours went | COMMENT |
| LOW | Controls/ThumbViewportFloorConverter.cs | 1 | using System; | COMMENT |
| LOW | Controls/Anim.cs | 1 | using System; | COMMENT |
| LOW | Controls/Anim.cs | 21 | // | COMMENT |
| LOW | Controls/Anim.cs | 101 | { | COMMENT |
| LOW | Controls/PrintPreviewWindow.cs | 1361 | /// every selected page has to be encoded into the XPS package there. Driven from the UI | COMMENT |
| LOW | Controls/SidebarPageBinding.cs | 1 | using System.Collections; | COMMENT |
| LOW | Controls/FileDialog.xaml.cs | 21 | /// Themed stand-in for Microsoft.Win32.OpenFileDialog / SaveFileDialog. Same chrome, places | COMMENT |
| LOW | Controls/FileDialog.xaml.cs | 221 | App.SetSetting("FileDlgY", Top.ToString(ci)); | COMMENT |
| LOW | Controls/DragCursors.cs | 1 | using System; | COMMENT |
| LOW | Controls/FolderTree.cs | 21 | // current folder on open instead), no shell context menu suite. | COMMENT |
| LOW | Controls/Viewer/PdfViewer.Links.cs | 21 | // Moved from Shell/Links.cs; the namespace and class line are the only changes. Window members | COMMENT |
| LOW | Controls/Viewer/PdfViewer.Links.cs | 41 | internal Dictionary<int, List<LinkInfo>> ContinuousLinks => _continuousLinks; | COMMENT |
| LOW | Controls/Viewer/PdfViewer.PageSelection.cs | 61 | /// XAML-bound handler. Replaces the old detach/attach of a cached delegate, which never | COMMENT |
| LOW | Controls/Viewer/PdfViewer.xaml.cs | 61 | /// <summary>Accent ring marking this pane as the focused one in a split. | COMMENT |
| LOW | Controls/Viewer/PdfViewer.Crop.cs | 21 | // Moved from Shell/Crop.cs; the namespace and class line are the only changes. Window members | COMMENT |
| LOW | Controls/Viewer/PdfViewer.TabStrip.cs | 1 | using System; | COMMENT |
| LOW | Controls/Viewer/PdfViewer.TabStrip.cs | 21 | // * UniformGrid divides the bounded host equally. The host grows only until the tabs reach | COMMENT |
| 37 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | App.xaml.cs | 474 | var source = System.Windows.Media.Imaging.BitmapFrame.Create(bitmap); | CODE |
| CRITICAL | Shell/Signing.cs | 853 | encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bmp)); | CODE |
| CRITICAL | Shell/ContextMenu.cs | 64 | var tileSource = System.Windows.Media.Imaging.BitmapFrame.Create(bmp); | CODE |
| CRITICAL | Controls/Viewer/PdfViewer.TabStrip.cs | 487 | var slot = System.Windows.Controls.Primitives.LayoutInformation.GetLayoutSlot(fe); | CODE |
| CRITICAL | Controls/Viewer/PdfViewer.TabStrip.cs | 592 | var slot = System.Windows.Controls.Primitives.LayoutInformation.GetLayoutSlot(dragged); | CODE |
| CRITICAL | engine/KillerPdf.Engine/Authoring/PdfDocumentBuilder.cs | 2693 | state.SoftMask.Backdrop.Value.Components.Select(Number)))); | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | Controls/Viewer/PdfViewer.Viewport.cs | 507 | // geometry never changes; they show the white scaffold until re-rendered (render cache | COMMENT |
| MEDIUM | Controls/Viewer/PdfViewer.Viewport.cs | 464 | Background = Brushes.White, // empty-page scaffold while the bitmap streams in (not a dark box) | CODE |
| MEDIUM | Controls/Viewer/PdfViewer.Viewport.cs | 707 | img.Source = null; // slot keeps its height; white scaffold shows until re-rendered | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | Shell/TempReload.cs | 109 | // robust error recovery and will rewrite a correct xref), then retry the open. | COMMENT |
| MEDIUM | pdf-landing/technical.html | 153 | <a href="#robust" data-i18n="pt_12">Robustness</a> | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | pdf-landing/engine/engine-docs-content.js | 1 | (function(){window.KPDF_ENGINE_DOCS={"api":"# API guide\n\nThe public API is organized by PDF responsibility. Start with | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pdf-landing/kp.js | 404 | function highlightStaticCodeBlocks() { | CODE |