uom has not been released yet. Until 1.0, only the latest release (and the main branch) receives fixes; from 1.0,
the latest minor release of the current major version does.
Do not open a public issue. Report it privately through GitHub's private vulnerability reporting of TinyGearsOrg/tinyunits, or by email to the maintainer, Thomas Neidhart (thomas.neidhart@gmail.com). Include the version, a minimal reproduction and the impact you see. Reports are answered on a best-effort basis; a fix is released before the details are published.
Units and quantities are Serializable through serialization proxies. A proxy rebuilds the object through the public
factories, so reading re-checks the invariants and a forged stream that violates them fails with
InvalidObjectException. The steps of a multi-step converter that cannot be checked against its factor and offset
(a part over 4096 bits) are dropped, so it reads as one step. An alternate atom whose symbol is not registered, even
after the catalogs are loaded (an atom of a user .units file that is not loaded), cannot be checked and reads as an
unregistered atom. A quantity reads back through the factory of this implementation's provider, else of the current
ServiceProvider. Systems and formats are not serializable. The serialized form may change in any release
before 1.0 (see docs/API.md).
The checks run after the JDK has read the stream: the JDK allocates its arrays and strings, and resolves its classes,
before any of our code runs. Never read a stream you do not trust without an ObjectInputFilter that limits the sizes
and allows only the needed classes. This filter, also used by serialization() in
Examples.java, is a starting point:
maxarray=65536;maxbytes=1048576;maxdepth=20;maxrefs=10000;org.tinygears.uom.core.**;org.tinygears.uom.quantity.*;javax.measure.**;java.lang.*;java.math.*;!*
The allow-list needs org.tinygears.uom.quantity too, because the filter also checks the classes the proxies resolve
to. Set it for the whole JVM with -Djdk.serialFilter=<filter>, or per stream:
String filter = "maxarray=65536;maxbytes=1048576;maxdepth=20;maxrefs=10000;"
+ "org.tinygears.uom.core.**;org.tinygears.uom.quantity.*;javax.measure.**;java.lang.*;java.math.*;!*";
Length length = Length.of(new BigDecimal("1.50"), SI.KILOMETRE);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (ObjectOutputStream out = new ObjectOutputStream(bytes)) {
out.writeObject(length);
}
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) {
in.setObjectInputFilter(ObjectInputFilter.Config.createFilter(filter));
Object read = in.readObject();
System.out.println(read + " " + read.equals(length)); // prints: 1.50 km true
}Loading a .units file runs no code, but its ~ lines register symbols for the life of the JVM, and its includes
read files: load files only from trusted locations. See the caveats in docs/CUSTOM-UNITS.md.