Class AvatarImageProcessor
java.lang.Object
com.kingsrook.qqq.backend.core.actions.profile.AvatarImageProcessor
Turns an uploaded image into the standard avatar sizes, safely:
- the type comes from the file's magic bytes only (PNG, JPEG, GIF, WebP);
SVG, HTML and everything else is refused, so no script can be served;
- the size and the pixel dimensions are bounded before decoding (a
decompression bomb is refused from its header);
- the image is decoded, centre-cropped square, turned upright (JPEG EXIF
orientation), resized, and re-encoded as PNG: re-encoding drops all
metadata (EXIF and its GPS position, XMP, comments).
Inline and bounded (a few hundred milliseconds at the limits), so it runs
in the request rather than as a durable job; at most MAX_CONCURRENT_DECODES
run at once per node. Everything stays in memory: ImageIO's file cache is
never used (no temporary files).
-
Method Summary
Modifier and TypeMethodDescriptionstatic StringdetectFormat(byte[] bytes) The image format named by the file's first bytes, or null when it is not an accepted raster type.process(byte[] bytes) Validate and convert: PNG bytes for each of UserProfilesMetaData.AVATAR_SIZES (keyed by size, in ascending order).static byte[]readBounded(InputStream inputStream, long maxBytes) Read at most maxBytes from the stream; refuse anything larger.
-
Method Details
-
readBounded
public static byte[] readBounded(InputStream inputStream, long maxBytes) throws IOException, QBadRequestException Read at most maxBytes from the stream; refuse anything larger.- Throws:
IOExceptionQBadRequestException
-
detectFormat
The image format named by the file's first bytes, or null when it is not an accepted raster type. Never trusts a file name or a declared content type. -
process
Validate and convert: PNG bytes for each of UserProfilesMetaData.AVATAR_SIZES (keyed by size, in ascending order).- Throws:
QBadRequestException
-