Skip to content

Commit 5f1bff3

Browse files
committed
refactor, check dataset thumb as well
1 parent 7725132 commit 5f1bff3

3 files changed

Lines changed: 79 additions & 66 deletions

File tree

src/main/java/edu/harvard/iq/dataverse/DatasetWidgetsPage.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99
import edu.harvard.iq.dataverse.util.BundleUtil;
1010
import edu.harvard.iq.dataverse.util.FileUtil;
1111
import edu.harvard.iq.dataverse.util.JsfHelper;
12+
import edu.harvard.iq.dataverse.util.SystemConfig;
13+
1214
import java.io.File;
1315
import java.io.IOException;
1416
import java.util.List;
1517
import java.util.logging.Level;
1618
import java.util.logging.Logger;
1719
import jakarta.ejb.EJB;
20+
import jakarta.faces.application.FacesMessage;
21+
import jakarta.faces.context.FacesContext;
1822
import jakarta.faces.view.ViewScoped;
1923
import jakarta.inject.Inject;
2024
import jakarta.inject.Named;
@@ -32,6 +36,9 @@ public class DatasetWidgetsPage implements java.io.Serializable {
3236

3337
@EJB
3438
EjbDataverseEngine commandEngine;
39+
40+
@EJB
41+
SystemConfig systemConfig;
3542

3643
@Inject
3744
DataverseRequestServiceBean dvRequestService;
@@ -131,6 +138,12 @@ public void flagDatasetThumbnailForRemoval() {
131138
public void handleImageFileUpload(FileUploadEvent event) {
132139
logger.fine("handleImageFileUpload clicked");
133140
UploadedFile uploadedFile = event.getFile();
141+
long maxSize = systemConfig.getThumbnailSizeLimitImage();
142+
if (!FileUtil.isUploadedFileAnImage(uploadedFile, maxSize)) {
143+
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Only image files are allowed.", "Only image files under " + maxSize + " bytes are allowed.");
144+
FacesContext.getCurrentInstance().addMessage(null, msg);
145+
return;
146+
}
134147
try {
135148
updateDatasetThumbnailCommand = new UpdateDatasetThumbnailCommand(dvRequestService.getDataverseRequest(), dataset, UpdateDatasetThumbnailCommand.UserIntent.setNonDatasetFileAsThumbnail, null, uploadedFile.getInputStream());
136149
} catch (IOException ex) {

src/main/java/edu/harvard/iq/dataverse/ThemeWidgetFragment.java

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import edu.harvard.iq.dataverse.engine.command.impl.UpdateDataverseThemeCommand;
1010
import edu.harvard.iq.dataverse.settings.JvmSettings;
1111
import edu.harvard.iq.dataverse.util.BundleUtil;
12+
import edu.harvard.iq.dataverse.util.FileUtil;
1213
import edu.harvard.iq.dataverse.util.JsfHelper;
1314
import edu.harvard.iq.dataverse.util.SystemConfig;
1415

@@ -238,9 +239,10 @@ public void handleImageThumbnailFileUpload(FileUploadEvent event) {
238239
logger.finer("created tempDir");
239240
}
240241
final UploadedFile uFile = event.getFile();
241-
if(!isImageFile(uFile)) {
242+
if(!FileUtil.isUploadedFileAnImage(uFile, getMaxSize())) {
242243
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Only image files are allowed.", "Only image files under " + getMaxSize() + " bytes are allowed.");
243244
FacesContext.getCurrentInstance().addMessage(null, msg);
245+
return;
244246
}
245247
try {
246248
this.uploadedFileThumbnail = new File(tempDir, uFile.getFileName());
@@ -272,9 +274,10 @@ public void handleImageFooterFileUpload(FileUploadEvent event) {
272274
logger.finer("created tempDir");
273275
}
274276
UploadedFile uFile = event.getFile();
275-
if (!isImageFile(uFile)) {
277+
if (!FileUtil.isUploadedFileAnImage(uFile, getMaxSize())) {
276278
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Only image files are allowed.", "Only image files under " + getMaxSize() + " bytes are allowed.");
277279
FacesContext.getCurrentInstance().addMessage(null, msg);
280+
return;
278281
}
279282

280283
try {
@@ -302,9 +305,10 @@ public void handleImageFileUpload(FileUploadEvent event) {
302305
logger.finer("created tempDir");
303306
}
304307
UploadedFile uFile = event.getFile();
305-
if (!isImageFile(uFile)) {
308+
if (!FileUtil.isUploadedFileAnImage(uFile, getMaxSize())) {
306309
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Only image files are allowed.", "Only image files under " + getMaxSize() + " bytes are allowed.");
307310
FacesContext.getCurrentInstance().addMessage(null, msg);
311+
return;
308312
}
309313
try {
310314
uploadedFile = new File(tempDir, uFile.getFileName());
@@ -453,64 +457,6 @@ public boolean exectThemeCommand(Command<Dataverse> cmd){
453457
return true;
454458
}
455459

456-
457-
/**
458-
* Verifies that an uploaded file is a valid image file. Performs both MIME type checking and content validation.
459-
*
460-
* @param uploadedFile
461-
* the file to verify
462-
* @throws ValidatorException
463-
* if the file is not a valid image
464-
*/
465-
private boolean isImageFile(UploadedFile uploadedFile) {
466-
if (uploadedFile == null) {
467-
return false;
468-
}
469-
470-
// Pre-filter: Check MIME type first (fast rejection)
471-
String contentType = uploadedFile.getContentType();
472-
if (contentType == null || !contentType.startsWith("image/")) {
473-
return false;
474-
}
475-
476-
// Check against allowed MIME types
477-
Set<String> allowedMimeTypes = Set.of(
478-
"image/jpeg",
479-
"image/jpg",
480-
"image/png",
481-
"image/gif",
482-
"image/tiff",
483-
"image/tif");
484-
485-
if (!allowedMimeTypes.contains(contentType.toLowerCase())) {
486-
return false;
487-
}
488-
489-
// Validate actual image content (security check)
490-
try (InputStream inputStream = uploadedFile.getInputStream()) {
491-
BufferedImage image = ImageIO.read(inputStream);
492-
if (image == null) {
493-
return false;
494-
}
495-
496-
// Optional: Check file size limit (similar to DataverseFeaturedItemServiceBean)
497-
498-
if (uploadedFile.getSize() > getMaxSize()) {
499-
return false;
500-
}
501-
502-
// Optional: Check image dimensions if needed
503-
int width = image.getWidth();
504-
int height = image.getHeight();
505-
logger.fine("Uploaded image dimensions: " + width + "x" + height);
506-
507-
} catch (IOException e) {
508-
logger.log(Level.WARNING, "Error reading uploaded image file", e);
509-
return false;
510-
}
511-
return true;
512-
}
513-
514460
// Initialize maxSize from systemConfig
515461
public long getMaxSize() {
516462
if (maxSize == 0) {

src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,11 @@
3434
import static edu.harvard.iq.dataverse.datasetutility.FileSizeChecker.bytesToHumanReadable;
3535
import edu.harvard.iq.dataverse.ingest.IngestReport;
3636
import edu.harvard.iq.dataverse.ingest.IngestServiceBean;
37-
import edu.harvard.iq.dataverse.ingest.IngestServiceShapefileHelper;
3837
import edu.harvard.iq.dataverse.ingest.IngestableDataChecker;
3938
import edu.harvard.iq.dataverse.license.License;
4039
import edu.harvard.iq.dataverse.settings.ConfigCheckService;
4140
import edu.harvard.iq.dataverse.settings.JvmSettings;
4241
import edu.harvard.iq.dataverse.util.file.BagItFileHandler;
43-
import edu.harvard.iq.dataverse.util.file.CreateDataFileResult;
4442
import edu.harvard.iq.dataverse.util.file.BagItFileHandlerFactory;
4543
import edu.harvard.iq.dataverse.util.xml.XmlUtil;
4644
import edu.harvard.iq.dataverse.util.xml.html.HtmlFormatUtil;
@@ -54,6 +52,7 @@
5452
import static edu.harvard.iq.dataverse.util.xml.html.HtmlFormatUtil.formatTableCellAlignRight;
5553
import static edu.harvard.iq.dataverse.util.xml.html.HtmlFormatUtil.formatTableRow;
5654

55+
import java.awt.image.BufferedImage;
5756
import java.io.BufferedInputStream;
5857
import java.io.File;
5958
import java.io.FileInputStream;
@@ -64,7 +63,6 @@
6463
import java.io.InputStream;
6564
import java.io.OutputStream;
6665
import java.nio.ByteBuffer;
67-
import java.nio.charset.Charset;
6866
import java.nio.file.Files;
6967
import java.nio.file.Path;
7068
import java.nio.file.Paths;
@@ -82,7 +80,7 @@
8280
import java.util.HashMap;
8381
import java.util.List;
8482
import java.util.Optional;
85-
import java.util.ResourceBundle;
83+
import java.util.Set;
8684
import java.util.UUID;
8785
import java.util.logging.Level;
8886
import java.util.logging.Logger;
@@ -92,6 +90,7 @@
9290
import jakarta.json.JsonArray;
9391
import jakarta.json.JsonObject;
9492

93+
import javax.imageio.ImageIO;
9594
import javax.xml.stream.XMLInputFactory;
9695
import javax.xml.stream.XMLStreamConstants;
9796
import javax.xml.stream.XMLStreamException;
@@ -106,9 +105,10 @@
106105
import edu.harvard.iq.dataverse.util.file.FileExceedsStorageQuotaException;
107106
import java.nio.charset.StandardCharsets;
108107
import java.util.Arrays;
109-
import org.apache.commons.io.IOUtils;
110108
import org.apache.commons.lang3.StringUtils;
111109
import org.apache.tika.Tika;
110+
import org.primefaces.model.file.UploadedFile;
111+
112112
import ucar.nc2.NetcdfFile;
113113
import ucar.nc2.NetcdfFiles;
114114

@@ -1900,5 +1900,59 @@ public static String decodeFileName(String originalFileName) {
19001900
}
19011901
return new String(originalFileName.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
19021902
}
1903+
1904+
/**
1905+
* Verifies that an uploaded file is a valid png or jpg image file. Performs both MIME type checking and content validation.
1906+
*
1907+
* @param uploadedFile
1908+
* the file to verify
1909+
* @param maxSize
1910+
* maximum allowed file size in bytes
1911+
*/
1912+
public static boolean isUploadedFileAnImage(UploadedFile uploadedFile, long maxSize) {
1913+
if (uploadedFile == null) {
1914+
return false;
1915+
}
1916+
1917+
// Pre-filter: Check MIME type first (fast rejection)
1918+
String contentType = uploadedFile.getContentType();
1919+
if (contentType == null || !contentType.startsWith("image/")) {
1920+
return false;
1921+
}
1922+
1923+
// Check against allowed MIME types
1924+
Set<String> allowedMimeTypes = Set.of(
1925+
"image/jpeg",
1926+
"image/jpg",
1927+
"image/png");
1928+
1929+
if (!allowedMimeTypes.contains(contentType.toLowerCase())) {
1930+
return false;
1931+
}
1932+
1933+
// Validate actual image content (security check)
1934+
try (InputStream inputStream = uploadedFile.getInputStream()) {
1935+
BufferedImage image = ImageIO.read(inputStream);
1936+
if (image == null) {
1937+
return false;
1938+
}
1939+
1940+
// Optional: Check file size limit (similar to DataverseFeaturedItemServiceBean)
1941+
1942+
if (uploadedFile.getSize() > maxSize) {
1943+
return false;
1944+
}
1945+
1946+
// Optional: Check image dimensions if needed
1947+
int width = image.getWidth();
1948+
int height = image.getHeight();
1949+
logger.fine("Uploaded image dimensions: " + width + "x" + height);
1950+
1951+
} catch (IOException e) {
1952+
logger.log(Level.WARNING, "Error reading uploaded image file", e);
1953+
return false;
1954+
}
1955+
return true;
1956+
}
19031957

19041958
}

0 commit comments

Comments
 (0)