chore: optimize pre-commit, remove tracked binaries, fix lint issues

- Move slow hooks (mypy, pylint, bandit, pytest, prettier) to pre-push stage
- Remove redundant autoflake (ruff covers F401/F841)
- Fix shellcheck OOM by batching files with xargs -n 40
- Remove tracked .o, .wav, .pyc binaries from git
- Move pomodoro wav files to ../testsAndMisc_binaries/ with symlinks
- Add *.o, *.so, *.a to .gitignore
- Refactor hltb._pick_best_hltb_entry to fix C901/PLR0911/SIM102
- Fix SC2034 warnings in gif_to_square.sh and upgrade.sh
- Add disk_cleanup_check.sh script
- Various test and code improvements across screen_locker,
  steam_backlog_enforcer, word_frequency, moviepy_showcase
This commit is contained in:
Krzysztof kuhy Rudnicki 2026-04-10 18:44:51 +02:00
parent 864b82efb6
commit ee41f014b2
20 changed files with 153 additions and 79 deletions

View File

@ -16,7 +16,7 @@ Checks: >
-readability-isolate-declaration,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
WarningsAsErrors: ''
WarningsAsErrors: ""
HeaderFilterRegex: '.*\.h$'
AnalyzeTemporaryDtors: false
FormatStyle: file

View File

@ -1,43 +1,35 @@
{
"C_Cpp.default.cStandard": "c99",
"C_Cpp.default.intelliSenseMode": "linux-gcc-x64",
"C_Cpp.default.includePath": [
"${workspaceFolder}/**",
"/usr/include/SDL2"
],
"C_Cpp.default.defines": [
"_REENTRANT"
],
"C_Cpp.default.compilerPath": "/usr/bin/gcc",
"C_Cpp.clang_format_style": "file",
"C_Cpp.clang_format_fallbackStyle": "LLVM",
"C_Cpp.default.cStandard": "c99",
"C_Cpp.default.intelliSenseMode": "linux-gcc-x64",
"C_Cpp.default.includePath": ["${workspaceFolder}/**", "/usr/include/SDL2"],
"C_Cpp.default.defines": ["_REENTRANT"],
"C_Cpp.default.compilerPath": "/usr/bin/gcc",
"C_Cpp.clang_format_style": "file",
"C_Cpp.clang_format_fallbackStyle": "LLVM",
"files.associations": {
"*.h": "c",
"*.c": "c"
},
"files.associations": {
"*.h": "c",
"*.c": "c"
},
"editor.formatOnSave": true,
"editor.tabSize": 4,
"editor.insertSpaces": true,
"editor.rulers": [100],
"editor.formatOnSave": true,
"editor.tabSize": 4,
"editor.insertSpaces": true,
"editor.rulers": [100],
"clang-tidy.executable": "clang-tidy",
"clang-tidy.checks": [
"clang-diagnostic-*",
"clang-analyzer-*",
"bugprone-*",
"cert-*",
"misc-*",
"performance-*",
"portability-*",
"readability-*"
],
"clang-tidy.executable": "clang-tidy",
"clang-tidy.checks": [
"clang-diagnostic-*",
"clang-analyzer-*",
"bugprone-*",
"cert-*",
"misc-*",
"performance-*",
"portability-*",
"readability-*"
],
"cppcheck.enable": true,
"cppcheck.standard": ["c99"],
"cppcheck.suppress": [
"missingIncludeSystem",
"unusedFunction"
]
"cppcheck.enable": true,
"cppcheck.standard": ["c99"],
"cppcheck.suppress": ["missingIncludeSystem", "unusedFunction"]
}

View File

@ -5,26 +5,31 @@ This directory contains a comprehensive linting setup for the imageViewer C proj
## Tools Included
### 1. **clang-tidy** - Static Analysis
- Configuration: `.clang-tidy`
- Checks for bugs, performance issues, and style violations
- Enforces modern C coding standards
### 2. **clang-format** - Code Formatting
### 2. **clang-format** - Code Formatting
- Configuration: `.clang-format`
- Automatically formats code to consistent style
- 100-character line limit, 4-space indentation
### 3. **cppcheck** - Additional Static Analysis
- Detects memory leaks, null pointer dereferences
- Checks for undefined behavior
### 4. **gcc with warnings** - Compiler Analysis
- Comprehensive warning flags
- Standards compliance checking
## Usage
### Quick Start
```bash
# Install dependencies (Arch Linux)
make deps-arch
@ -43,6 +48,7 @@ make memcheck
```
### Individual Commands
```bash
# Manual linting
./lint.sh
@ -60,12 +66,14 @@ cppcheck --enable=all main.c
## VS Code Integration
The `.vscode/settings.json` file provides:
- Automatic formatting on save
- C99 standard compliance
- IntelliSense configuration for SDL2
- Integrated linting with clang-tidy and cppcheck
## Recommended Extensions for VS Code
- C/C++ (Microsoft)
- clang-tidy (mine-cetinkaya-fianso)
- cppcheck (unixwrapped)
@ -73,16 +81,18 @@ The `.vscode/settings.json` file provides:
## Linting Rules
### Enabled Checks
- **clang-diagnostic-***: Compiler diagnostics
- **clang-analyzer-***: Static analysis
- **bugprone-***: Bug-prone patterns
- **cert-***: CERT secure coding standards
- **misc-***: Miscellaneous checks
- **performance-***: Performance improvements
- **portability-***: Cross-platform issues
- **readability-***: Code readability
- **clang-diagnostic-\***: Compiler diagnostics
- **clang-analyzer-\***: Static analysis
- **bugprone-\***: Bug-prone patterns
- **cert-\***: CERT secure coding standards
- **misc-\***: Miscellaneous checks
- **performance-\***: Performance improvements
- **portability-\***: Cross-platform issues
- **readability-\***: Code readability
### Disabled Checks
- `readability-magic-numbers`: Allows constants like window dimensions
- `cert-err33-c`: Allows ignoring some function return values
- `misc-unused-parameters`: Common in callback functions
@ -107,16 +117,19 @@ The `.vscode/settings.json` file provides:
## Installation on Different Systems
### Arch Linux
```bash
sudo pacman -S clang cppcheck valgrind
```
### Ubuntu/Debian
```bash
sudo apt install clang-tidy cppcheck clang-format valgrind
```
### Fedora/RHEL
```bash
sudo dnf install clang-tools-extra cppcheck clang valgrind
```

View File

@ -16,22 +16,26 @@ A simple, lightweight image viewer written in C using SDL2. Supports JPG, PNG, B
The image viewer requires SDL2 and SDL2_image libraries.
### Ubuntu/Debian
```bash
sudo apt-get update
sudo apt-get install libsdl2-dev libsdl2-image-dev
```
### Fedora/RHEL/CentOS
```bash
sudo dnf install SDL2-devel SDL2_image-devel
```
### Arch Linux
```bash
sudo pacman -S sdl2 sdl2_image
```
### macOS (with Homebrew)
```bash
brew install sdl2 sdl2_image
```
@ -39,6 +43,7 @@ brew install sdl2 sdl2_image
## Installation
### Arch Linux (Automated)
For Arch Linux users, there's an automated installation script that handles everything:
```bash
@ -46,6 +51,7 @@ For Arch Linux users, there's an automated installation script that handles ever
```
This script will:
- Install SDL2 dependencies via pacman
- Build the imageviewer from source
- Install the binary to `/usr/local/bin`
@ -53,6 +59,7 @@ This script will:
- Set up file associations
To uninstall:
```bash
./uninstall_arch.sh
```
@ -61,14 +68,16 @@ To uninstall:
1. Install dependencies (see above)
2. Build the project:
```bash
make
```
Or use the dependency helper:
```bash
make deps-debian # For Ubuntu/Debian
make deps-fedora # For Fedora/RHEL/CentOS
make deps-fedora # For Fedora/RHEL/CentOS
make deps-arch # For Arch Linux
make
```
@ -80,6 +89,7 @@ make
```
Example:
```bash
./imageviewer photo.jpg
./imageviewer ../misc/randomJPG/14k/bloated_image_1.jpg
@ -87,35 +97,39 @@ Example:
## Controls
| Control | Action |
|---------|--------|
| **Mouse wheel** | Zoom in/out |
| **+ / -** | Zoom in/out (keyboard) |
| **Mouse drag** | Pan around the image |
| **R** | Reset zoom and position to default |
| **F** | Fit image to window |
| **H** | Show help in console |
| **ESC / Q** | Quit the application |
| Control | Action |
| --------------- | ---------------------------------- |
| **Mouse wheel** | Zoom in/out |
| **+ / -** | Zoom in/out (keyboard) |
| **Mouse drag** | Pan around the image |
| **R** | Reset zoom and position to default |
| **F** | Fit image to window |
| **H** | Show help in console |
| **ESC / Q** | Quit the application |
## Features in Detail
### Zooming
- Use mouse wheel to zoom in/out at the mouse cursor position
- Keyboard shortcuts: `+` to zoom in, `-` to zoom out
- Zoom range: 0.1x to 10x
- Smart zoom behavior focuses on mouse position
### Panning
- Click and drag with left mouse button to move around zoomed images
- Smooth panning for precise positioning
- Works at any zoom level
### Auto-fit
- Large images are automatically scaled to fit the window when first loaded
- Press `F` to manually fit the current image to window
- Maintains aspect ratio
### Window Management
- Resizable window that adapts to content
- Real-time rendering updates
- Dark background for better image contrast
@ -141,7 +155,9 @@ Example:
## Troubleshooting
### "SDL could not initialize" Error
Make sure SDL2 development libraries are installed:
```bash
# Ubuntu/Debian
sudo apt-get install libsdl2-dev libsdl2-image-dev
@ -151,11 +167,13 @@ pkg-config --libs sdl2
```
### "Unable to load image" Error
- Check that the image file exists and is readable
- Verify the image format is supported (JPG, PNG, BMP, GIF, TIF)
- Try with a different image file to isolate the issue
### Compilation Errors
- Ensure you have a C compiler installed (gcc or clang)
- Check that SDL2 headers are available
- Try rebuilding with `make clean && make`

View File

@ -7,6 +7,7 @@ The imageviewer project uses secure coding practices with proper bounds checking
### Why These Warnings Appear
The static analyzer flags standard C library functions like:
- `memcpy()` - suggests using `memcpy_s()`
- `snprintf()` - suggests using `snprintf_s()`
- `strncpy()` - suggests using `strncpy_s()`
@ -34,9 +35,10 @@ if (ret < 0 || ret >= sizeof(full_path)) {
}
```
### Microsoft-Specific _s Functions
### Microsoft-Specific \_s Functions
The suggested `_s` functions (like `memcpy_s`, `snprintf_s`) are:
- Microsoft-specific extensions
- Not part of standard C
- Not portable to Linux/Unix systems
@ -47,6 +49,7 @@ The suggested `_s` functions (like `memcpy_s`, `snprintf_s`) are:
**Status**: ✅ **SECURE**
The current implementation is secure because:
- All buffer operations are bounds-checked
- No user input is directly copied without validation
- File paths are validated for maximum length
@ -63,6 +66,7 @@ For development, these specific warnings can be suppressed since the code has be
```
Or use NOLINT comments for specific lines:
```c
memcpy(dest, src, len); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
```
@ -70,6 +74,7 @@ memcpy(dest, src, len); // NOLINT(clang-analyzer-security.insecureAPI.Deprecated
### Verification
To verify security:
1. ✅ All string operations use explicit length checking
2. ✅ Buffer overflow conditions are detected and handled
3. ✅ No direct user input to buffer operations

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
../../../../../testsAndMisc_binaries/horatio_demo_recordings/hamlet_line0_take1.wav

View File

@ -1 +0,0 @@
../../../../../testsAndMisc_binaries/horatio_demo_recordings/hamlet_line0_take2.wav

View File

@ -1 +0,0 @@
../../../../../testsAndMisc_binaries/horatio_demo_recordings/hamlet_line0_take3.wav

View File

@ -1 +0,0 @@
../../../../../testsAndMisc_binaries/horatio_demo_recordings/hamlet_line1_take1.wav

View File

@ -6,6 +6,7 @@ so source modules can be imported without moviepy installed.
from __future__ import annotations
import importlib
import sys
from typing import Any
from unittest.mock import MagicMock
@ -70,25 +71,38 @@ _clip_classes = [
"AudioArrayClip",
"CompositeAudioClip",
]
for _cls in _clip_classes:
getattr(mock_moviepy, _cls).side_effect = lambda *_a, **_kw: create_mock_clip()
mock_moviepy.concatenate_videoclips.side_effect = lambda *_a, **_kw: create_mock_clip()
mock_moviepy.concatenate_audioclips.side_effect = lambda *_a, **_kw: create_mock_clip()
mock_moviepy.video.compositing.CompositeVideoClip.clips_array.side_effect = (
lambda *_a, **_kw: create_mock_clip()
)
_drawing_shape = (_H, _W)
# Drawing tools must return real numpy arrays (used in numpy ops)
mock_moviepy.video.tools.drawing.circle.return_value = np.zeros(
(_H, _W), dtype=np.float64
)
mock_moviepy.video.tools.drawing.color_gradient.return_value = np.zeros(
(_H, _W), dtype=np.float64
)
mock_moviepy.video.tools.drawing.color_split.return_value = np.zeros(
(_H, _W), dtype=np.float64
)
def _reset_side_effects() -> None:
"""(Re)apply side_effect / return_value on the shared mock_moviepy."""
for cls_name in _clip_classes:
getattr(mock_moviepy, cls_name).side_effect = lambda *_a, **_kw: (
create_mock_clip()
)
mock_moviepy.concatenate_videoclips.side_effect = lambda *_a, **_kw: (
create_mock_clip()
)
mock_moviepy.concatenate_audioclips.side_effect = lambda *_a, **_kw: (
create_mock_clip()
)
mock_moviepy.video.compositing.CompositeVideoClip.clips_array.side_effect = (
lambda *_a, **_kw: create_mock_clip()
)
# Drawing tools must return real numpy arrays (used in numpy ops)
mock_moviepy.video.tools.drawing.circle.return_value = np.zeros(
_drawing_shape, dtype=np.float64
)
mock_moviepy.video.tools.drawing.color_gradient.return_value = np.zeros(
_drawing_shape, dtype=np.float64
)
mock_moviepy.video.tools.drawing.color_split.return_value = np.zeros(
_drawing_shape, dtype=np.float64
)
_reset_side_effects()
# ── Install into sys.modules ─────────────────────────────────────
_module_paths = [
@ -117,7 +131,21 @@ def _install_moviepy_mocks() -> None:
_install_moviepy_mocks()
_source_modules = [
"python_pkg.moviepy_showcase.moviepy_showcase",
"python_pkg.moviepy_showcase._moviepy_clip_types",
"python_pkg.moviepy_showcase._moviepy_video_effects",
"python_pkg.moviepy_showcase._moviepy_audio_output",
]
@pytest.fixture(autouse=True)
def _reinstall_moviepy_mocks() -> None:
"""Ensure our moviepy mocks are active even if another conftest overwrote."""
_install_moviepy_mocks()
_reset_side_effects()
# Re-bind cached ``from moviepy import X`` references in source modules
# that may point to stale MagicMock children from a prior sys.modules entry.
for mod_name in _source_modules:
if mod_name in sys.modules:
importlib.reload(sys.modules[mod_name])

View File

@ -325,3 +325,25 @@ class TestArgosImportReload:
importlib.reload(_helpers)
# Restore original module state
importlib.reload(_helpers)
class TestTorchImportReload:
"""Test import-time torch ImportError branch via reload."""
def test_torch_import_failure_reload(self) -> None:
"""Cover lines 19-20 (except ImportError: torch = None) via reload."""
import builtins
original_import = builtins.__import__
def _block_torch(name: str, *args: object, **kwargs: object) -> object:
if name == "torch":
msg = "mocked torch unavailable"
raise ImportError(msg)
return original_import(name, *args, **kwargs)
with patch.object(builtins, "__import__", side_effect=_block_torch):
importlib.reload(_helpers)
assert _helpers.torch is None
# Restore original module state
importlib.reload(_helpers)