package com.xfestudio.xfeservermanager.infra.content;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
class ContentAssetStoreTest {
@TempDir Path directory;
@Test
void storesByDigestDeduplicatesAndNeverUsesTheDisplayNameAsAPath() throws Exception {
ContentAssetStore store = new ContentAssetStore(directory.resolve("assets"));
byte[] png = png(2, 2);
var asset = store.upload("../outside.png", "image/png", Base64.getEncoder().encodeToString(png));
assertThat(asset.id()).isEqualTo(ContentAssetStore.sha256(png));
assertThat(asset.resourceLocation()).isEqualTo("xfesmcontent:uploaded_" + asset.id());
assertThat(store.read(asset)).isEqualTo(png);
assertThat(store.upload("Renamed.png", "image/png", Base64.getEncoder().encodeToString(png))).isEqualTo(asset);
assertThat(store.list()).containsExactly(asset);
assertThat(Files.exists(directory.resolve("outside.png"))).isFalse();
}
@Test
void rejectsMalformedMediaOversizedImagesAndTamperedBlobs() throws Exception {
ContentAssetStore store = new ContentAssetStore(directory);
assertThatThrownBy(() -> store.upload("Bad", "image/svg+xml", "")).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> store.upload("Bad", "image/png", "!!!")).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> store.upload("Bad", "image/png", Base64.getEncoder().encodeToString(new byte[40]))).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> store.upload("Huge", "image/png", Base64.getEncoder().encodeToString(png(2049, 1)))).isInstanceOf(IllegalArgumentException.class);
byte[] valid = png(2, 2);
byte[] truncated = java.util.Arrays.copyOf(valid, 35);
assertThatThrownBy(() -> store.upload("Truncated", "image/png", Base64.getEncoder().encodeToString(truncated))).isInstanceOf(Exception.class);
var asset = store.upload("Good", "image/png", Base64.getEncoder().encodeToString(valid));
byte[] modified = valid.clone(); modified[modified.length - 1] ^= 1;
Files.write(directory.resolve(asset.id() + ".bin"), modified);
assertThatThrownBy(() -> store.read(asset)).hasMessageContaining("digest mismatch");
}
@Test
void rejectsForgedOggPagesWithNoCrcOrCodecHeaders() {
// Two superficially plausible pages passed the original boundary-only parser.
byte[] fake = new byte[88];
fake[0] = 'O'; fake[1] = 'g'; fake[2] = 'g'; fake[3] = 'S';
fake[26] = 1; fake[27] = 30; fake[28] = 1;
byte[] vorbis = "vorbis".getBytes(java.nio.charset.StandardCharsets.US_ASCII);
System.arraycopy(vorbis, 0, fake, 29, vorbis.length);
fake[39] = 2;
ByteBuffer.wrap(fake, 40, 4).order(ByteOrder.LITTLE_ENDIAN).putInt(44100);
fake[58] = 'O'; fake[59] = 'g'; fake[60] = 'g'; fake[61] = 'S';
fake[84] = 1; fake[85] = 2; fake[86] = 1;
assertThatThrownBy(() -> ContentAssetStore.validateMedia("audio/ogg", fake)).isInstanceOf(Exception.class);
}
@Test
void rejectsMetadataThatEscapesTheContentAddressedNamespace() throws Exception {
ContentAssetStore store = new ContentAssetStore(directory);
var asset = store.upload("Good", "image/png", Base64.getEncoder().encodeToString(png(1, 1)));
Path metadata = directory.resolve(asset.id() + ".json");
String original = Files.readString(metadata);
Files.writeString(metadata, original.replace(asset.resourceLocation(), "minecraft:unrelated"));
assertThatThrownBy(store::list).hasMessageContaining("metadata");
}
static byte[] png(int width, int height) throws Exception {
var output = new ByteArrayOutputStream();
ImageIO.write(new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB), "png", output);
return output.toByteArray();
}
}
package com.xfestudio.xfeservermanager.infra.content;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
class ContentAssetStoreTest {
@TempDir Path directory;
@Test
void storesByDigestDeduplicatesAndNeverUsesTheDisplayNameAsAPath() throws Exception {
ContentAssetStore store = new ContentAssetStore(directory.resolve("assets"));
byte[] png = png(2, 2);
var asset = store.upload("../outside.png", "image/png", Base64.getEncoder().encodeToString(png));
assertThat(asset.id()).isEqualTo(ContentAssetStore.sha256(png));
assertThat(asset.resourceLocation()).isEqualTo("xfesmcontent:uploaded_" + asset.id());
assertThat(store.read(asset)).isEqualTo(png);
assertThat(store.upload("Renamed.png", "image/png", Base64.getEncoder().encodeToString(png))).isEqualTo(asset);
assertThat(store.list()).containsExactly(asset);
assertThat(Files.exists(directory.resolve("outside.png"))).isFalse();
}
@Test
void rejectsMalformedMediaOversizedImagesAndTamperedBlobs() throws Exception {
ContentAssetStore store = new ContentAssetStore(directory);
assertThatThrownBy(() -> store.upload("Bad", "image/svg+xml", "")).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> store.upload("Bad", "image/png", "!!!")).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> store.upload("Bad", "image/png", Base64.getEncoder().encodeToString(new byte[40]))).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> store.upload("Huge", "image/png", Base64.getEncoder().encodeToString(png(2049, 1)))).isInstanceOf(IllegalArgumentException.class);
byte[] valid = png(2, 2);
byte[] truncated = java.util.Arrays.copyOf(valid, 35);
assertThatThrownBy(() -> store.upload("Truncated", "image/png", Base64.getEncoder().encodeToString(truncated))).isInstanceOf(Exception.class);
var asset = store.upload("Good", "image/png", Base64.getEncoder().encodeToString(valid));
byte[] modified = valid.clone(); modified[modified.length - 1] ^= 1;
Files.write(directory.resolve(asset.id() + ".bin"), modified);
assertThatThrownBy(() -> store.read(asset)).hasMessageContaining("digest mismatch");
}
@Test
void rejectsForgedOggPagesWithNoCrcOrCodecHeaders() {
// Two superficially plausible pages passed the original boundary-only parser.
byte[] fake = new byte[88];
fake[0] = 'O'; fake[1] = 'g'; fake[2] = 'g'; fake[3] = 'S';
fake[26] = 1; fake[27] = 30; fake[28] = 1;
byte[] vorbis = "vorbis".getBytes(java.nio.charset.StandardCharsets.US_ASCII);
System.arraycopy(vorbis, 0, fake, 29, vorbis.length);
fake[39] = 2;
ByteBuffer.wrap(fake, 40, 4).order(ByteOrder.LITTLE_ENDIAN).putInt(44100);
fake[58] = 'O'; fake[59] = 'g'; fake[60] = 'g'; fake[61] = 'S';
fake[84] = 1; fake[85] = 2; fake[86] = 1;
assertThatThrownBy(() -> ContentAssetStore.validateMedia("audio/ogg", fake)).isInstanceOf(Exception.class);
}
@Test
void rejectsMetadataThatEscapesTheContentAddressedNamespace() throws Exception {
ContentAssetStore store = new ContentAssetStore(directory);
var asset = store.upload("Good", "image/png", Base64.getEncoder().encodeToString(png(1, 1)));
Path metadata = directory.resolve(asset.id() + ".json");
String original = Files.readString(metadata);
Files.writeString(metadata, original.replace(asset.resourceLocation(), "minecraft:unrelated"));
assertThatThrownBy(store::list).hasMessageContaining("metadata");
}
static byte[] png(int width, int height) throws Exception {
var output = new ByteArrayOutputStream();
ImageIO.write(new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB), "png", output);
return output.toByteArray();
}
}