feat(fls): export the editor model's files

exportProject.ts, step X3: the files of a PC or notebook from the model's
virtual file system under Java's root. A file's type follows from its kind:
text by a known extension (else "text"), an image or binary data by its
media type. Images and binary data are Base64 as FILIUS's
Base64.encodeBytes (iHarder 2.x) writes it: a line break after every 76
characters, also after the last full line. Without that, all 31 images of
the corpus came back with other content. A new oracle tool, Base64Cases,
has Java encode 19 lengths around the line length; javaBase64 matches all.
A router or home router keeps the files its constructor makes.

Checked by Java: every corpus file, imported, exported and written, loads
with the files of the original, byte for byte, up to named departures of
the model: files in its order (directories first, then by name), with the
type of their kind rather than the one the file named (Java itself names
them unevenly), and no router files beyond the constructor's (www.conf,
16 times). The synthetic model adds nested directories, text with and
without a known extension, a PNG, a JPEG, binary data with and without a
media type and 57 bytes, one Base64 line exactly. 10 mutation probes, each
loaded by Java, were all caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 09:11:39 +00:00
co-authored by Claude Opus 5.5
parent d3f476269a
commit 698a775c37
8 changed files with 1777 additions and 106 deletions
+9
View File
@@ -98,6 +98,15 @@ passt. Je Kabel steht auch `panel`: die Geräte, zwischen denen die
Oberfläche es zeichnet (`JCablePanel.ziel1/ziel2`) — im Korpus bei allen 183
Kabeln die Geräte, die es verbindet.
## Wie Java Base64 schreibt
`Base64Cases` ruft Filius' eigenes `Base64.encodeBytes` (iHarder 2.x) auf
Byte-Folgen von 19 Längen rund um die Zeilenlänge auf
(`packages/fls/test/base64.java.json`). Befund: nach je 76 Zeichen ein
`\n`, auch nach der letzten vollen Zeile, dann der aufgefüllte Rest ohne
Umbruch. So stehen Bilder in den Dateien, auch die, die Javas Konstruktoren
selbst anlegen.
## Was Java aus unserem XML macht
`BeansDump` liest jede `*.xml` unter `packages/fls/test/beans/` mit
+7 -1
View File
@@ -21,7 +21,7 @@ if [ ! -f "$upstream/target/filius.jar" ]; then
fi
classpath="$upstream/target/filius.jar:$upstream/target/lib/*"
mkdir -p "$here/.build"
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java"
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java"
# FILIUS writes its settings below $HOME; keep them out of the real one.
mkdir -p "$here/.build/home"
# Removed first: a crashed run must not leave the previous result standing.
@@ -67,6 +67,12 @@ rm -f "$ipcheck"
HOME="$here/.build/home" java -cp "$classpath:$here/.build" IpCheckCases "$cases" "$ipcheck" 2>&1 | grep -v 'logback\|^$' || true
test -s "$ipcheck"
# Base64.encodeBytes around its line length (packages/fls/src/exportProject.ts, javaBase64).
base64="$root/packages/fls/test/base64.java.json"
rm -f "$base64"
HOME="$here/.build/home" java -cp "$classpath:$here/.build" Base64Cases "$base64" 0 1 2 3 55 56 57 58 59 113 114 115 116 171 172 2000 2001 2002 2052 2>&1 | grep -v 'logback\|^$' || true
test -s "$base64"
# DNSServer's own reading of /dns/hosts on hand-picked files (packages/fls/src/dnsHosts.ts).
cases="$root/packages/fls/test/dns-hosts.cases.txt"
dnshosts="$root/packages/fls/test/dns-hosts.java.json"
+32
View File
@@ -0,0 +1,32 @@
// Runs FILIUS's own Base64.encodeBytes on byte arrays of the given lengths
// and writes what Java returns — the reference for javaBase64 in
// packages/fls/src/exportProject.ts. The bytes of length n are
// (index * 37 + 11) mod 256, so both sides make them alike.
//
// Usage: java -cp filius.jar:lib/*:classes Base64Cases <output json> <length>...
import filius.rahmenprogramm.Base64;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Base64Cases {
public static void main(String[] args) throws Exception {
List<Object> result = new ArrayList<>();
for (int argument = 1; argument < args.length; argument++) {
int length = Integer.parseInt(args[argument]);
byte[] bytes = new byte[length];
for (int index = 0; index < length; index++) bytes[index] = (byte) ((index * 37 + 11) % 256);
result.add(Arrays.asList(length, Base64.encodeBytes(bytes)));
}
try (FileOutputStream out = new FileOutputStream(args[0])) {
out.write((FlsOracle.Json.write(result, "") + "\n").getBytes(StandardCharsets.UTF_8));
}
System.out.println("base64 cases: " + result.size());
System.exit(0);
}
}