From f4b28ecd5281d62ec1036497a973c9963680ade4 Mon Sep 17 00:00:00 2001 From: jonax1337 Date: Fri, 22 May 2026 12:17:08 +0200 Subject: [PATCH] fix(v0.16.1): KoSIT-Validator-Stdin auf Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KoSIT 1.6.x prüft via FileInputStream.available() ob stdin gepiped ist. Auf Windows wirft available() für character devices (geerbtes Console-Handle, auch NUL via Stdio::null) eine IOException, die KoSIT nicht fängt — Validator bricht ab bevor ein Report geschrieben wird. Fix: stdin aus leerer regulärer Datei füttern. Disk-type-Handle ist pollbar, available() liefert 0, isPiped() wird false. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 5 +++++ package.json | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/src/validator.rs | 13 ++++++++++++- src-tauri/tauri.conf.json | 2 +- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e75d180..3045d75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ Versionen folgen [Semantic Versioning](https://semver.org/lang/de/). ## [Unreleased] +## [0.16.1] + +### Fixed +- **KoSIT-Validator: `IOException: Unzulässige Funktion` auf Windows.** Der KoSIT-Validator prüft via `FileInputStream.available()`, ob seine stdin gepiped ist (`Validator.isPiped()`). Auf Windows wirft `available()` für character devices (geerbtes Console-Handle, auch `NUL` via `Stdio::null()`) eine `IOException` — KoSIT fängt das nicht und bricht ab, bevor überhaupt ein Report geschrieben wird. Folge: jede Validierung im Dev-Modus und auch in der installierten App lieferte „Kein Report gefunden. stderr: java.io.IOException: Unzulässige Funktion". Fix in `src-tauri/src/validator.rs`: stdin wird jetzt aus einer leeren regulären Datei gefüttert (disk-type-Handle, `available()` liefert sauber 0, `isPiped()` wird false). Datei wird pro Validierungs-Aufruf im Temp-Verzeichnis angelegt und sofort wieder aufgeräumt. + ## [0.16.0] > **Internationalisierung + Detail-Schliff.** Englische PDF-Variante, mehrsprachige Katalog-Beschreibungen, kuratierte Ausgaben-Kategorien mit SKR03/SKR04-Konten-Mapping, und Bulk-Aktionen jetzt auch für Angebote und Eingangsrechnungen. diff --git a/package.json b/package.json index 5be9181..76b97c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zettel", - "version": "0.16.0", + "version": "0.16.1", "description": "Offline-first invoice generator with ZUGFeRD/Factur-X support", "type": "module", "scripts": { diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 41d5f7c..882662d 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zettel" -version = "0.16.0" +version = "0.16.1" description = "Zettel — Offline-first invoice generator" authors = ["Jonas Laux"] edition = "2021" diff --git a/src-tauri/src/validator.rs b/src-tauri/src/validator.rs index 28e5bde..4504094 100644 --- a/src-tauri/src/validator.rs +++ b/src-tauri/src/validator.rs @@ -12,7 +12,7 @@ use crate::sidecar; use serde::Serialize; use std::path::{Path, PathBuf}; -use std::process::Command; +use std::process::{Command, Stdio}; use tauri::{AppHandle, Manager}; #[derive(Debug, Serialize)] @@ -175,6 +175,15 @@ pub async fn validate_einvoice_xml( std::fs::create_dir_all(&tmp).map_err(|e| format!("tmpdir: {}", e))?; let java = resolve_java(&app); + // KoSIT prüft `FileInputStream.available()` um stdin-Pipe-Mode zu erkennen. + // Auf Windows wirft `available()` für character devices (Console-Handle, + // NUL) eine `IOException: Unzulässige Funktion` — `Stdio::null()` reicht + // also nicht. Wir reichen eine leere reguläre Datei rein: disk-type ist + // pollbar, `available()` liefert sauber 0, `isPiped()` wird false. + let empty_stdin = tmp.join("empty-stdin"); + std::fs::write(&empty_stdin, b"").map_err(|e| format!("empty stdin write: {}", e))?; + let stdin_file = + std::fs::File::open(&empty_stdin).map_err(|e| format!("empty stdin open: {}", e))?; let output = Command::new(&java) .arg("-jar") .arg(&jar) @@ -185,6 +194,7 @@ pub async fn validate_einvoice_xml( .arg("-o") .arg(&tmp) .arg(input) + .stdin(Stdio::from(stdin_file)) .output() .map_err(|e| { format!( @@ -192,6 +202,7 @@ pub async fn validate_einvoice_xml( e ) })?; + let _ = std::fs::remove_file(&empty_stdin); // Validator returns non-zero on rejected input but still writes a report. let stderr = String::from_utf8_lossy(&output.stderr); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index d11d903..12617e7 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Zettel", - "version": "0.16.0", + "version": "0.16.1", "identifier": "digital.laux.zettel", "build": { "beforeDevCommand": "pnpm dev",