diff --git a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/configuration/Registration.java b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/configuration/Registration.java index 92c477234..884766d50 100644 --- a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/configuration/Registration.java +++ b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/configuration/Registration.java @@ -122,11 +122,9 @@ public void eventHandlers(CdsRuntimeConfigurer configurer) { // build malware scanner client, could be null if no service binding is available MalwareScanClient scanClient = buildMalwareScanClient(runtime.getEnvironment()); - // determine default max size based on malware scanner binding availability - String defaultMaxSize = - scanClient != null - ? ModifyApplicationHandlerHelper.DEFAULT_SIZE_WITH_SCANNER - : ModifyApplicationHandlerHelper.UNLIMITED_SIZE; + // determine default max size; independent of the scanner binding it stays finite so a missing + // scanner does not allow unbounded uploads. An explicit configuration can raise the limit. + String defaultMaxSize = resolveDefaultMaxSize(runtime.getEnvironment()); AttachmentMalwareScanner malwareScanner = new DefaultAttachmentMalwareScanner(persistenceService, attachmentService, scanClient); @@ -190,6 +188,26 @@ public void eventHandlers(CdsRuntimeConfigurer configurer) { } } + /** + * Resolves the default maximum upload size for attachment content. + * + *
An explicit {@code cds.attachments.maxUploadSize} configuration takes precedence. Otherwise
+ * a finite default is used regardless of the malware scanner binding, so that a missing scanner
+ * does not silently allow unbounded uploads. Consuming apps can still override the limit per
+ * entity via {@code @Validation.Maximum}.
+ *
+ * @param environment the {@link CdsEnvironment} to read configuration from
+ * @return the default maximum upload size as a size string (e.g. {@code "400MB"})
+ */
+ static String resolveDefaultMaxSize(CdsEnvironment environment) {
+ String configured =
+ environment.getProperty("cds.attachments.maxUploadSize", String.class, null);
+ if (configured != null && !configured.isBlank()) {
+ return configured;
+ }
+ return ModifyApplicationHandlerHelper.DEFAULT_MAX_UPLOAD_SIZE;
+ }
+
/**
* Builds the {@link MalwareScanClient malware scanner client} based on the service binding.
*
diff --git a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/applicationservice/helper/ModifyApplicationHandlerHelper.java b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/applicationservice/helper/ModifyApplicationHandlerHelper.java
index 2c315bbe9..ea7723286 100644
--- a/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/applicationservice/helper/ModifyApplicationHandlerHelper.java
+++ b/cds-feature-attachments/src/main/java/com/sap/cds/feature/attachments/handler/applicationservice/helper/ModifyApplicationHandlerHelper.java
@@ -23,11 +23,14 @@
public final class ModifyApplicationHandlerHelper {
- /** Default max size when malware scanner binding is present (400 MB). */
- public static final String DEFAULT_SIZE_WITH_SCANNER = "400MB";
-
- /** Effectively unlimited max size when no malware scanner binding is present. */
- public static final String UNLIMITED_SIZE = String.valueOf(Long.MAX_VALUE);
+ /**
+ * Default maximum upload size for attachment content (400 MB). A finite default is used
+ * regardless of the malware scanner binding so that a missing scanner does not silently allow
+ * unbounded uploads. It can be raised via the {@code cds.attachments.maxUploadSize} property or a
+ * per-entity {@code @Validation.Maximum} annotation, and matches the SAP Malware Scanning Service
+ * limit when a scanner is present.
+ */
+ public static final String DEFAULT_MAX_UPLOAD_SIZE = "400MB";
/**
* Handles attachments for entities.
diff --git a/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/configuration/RegistrationTest.java b/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/configuration/RegistrationTest.java
index 3a4726a50..7edfecd9e 100644
--- a/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/configuration/RegistrationTest.java
+++ b/cds-feature-attachments/src/test/java/com/sap/cds/feature/attachments/configuration/RegistrationTest.java
@@ -15,6 +15,7 @@
import com.sap.cds.feature.attachments.handler.applicationservice.DeleteAttachmentsHandler;
import com.sap.cds.feature.attachments.handler.applicationservice.ReadAttachmentsHandler;
import com.sap.cds.feature.attachments.handler.applicationservice.UpdateAttachmentsHandler;
+import com.sap.cds.feature.attachments.handler.applicationservice.helper.ModifyApplicationHandlerHelper;
import com.sap.cds.feature.attachments.handler.draftservice.DraftActiveAttachmentsHandler;
import com.sap.cds.feature.attachments.handler.draftservice.DraftCancelAttachmentsHandler;
import com.sap.cds.feature.attachments.handler.draftservice.DraftPatchAttachmentsHandler;
@@ -253,6 +254,35 @@ void environmentHandlesNullExistingPaths() {
"../target/cds/com.sap.cds/cds-feature-attachments/**");
}
+ @Test
+ void resolveDefaultMaxSize_returnsFiniteDefaultWhenNoConfig() {
+ CdsEnvironment environment = mock(CdsEnvironment.class);
+ when(environment.getProperty("cds.attachments.maxUploadSize", String.class, null))
+ .thenReturn(null);
+
+ assertThat(Registration.resolveDefaultMaxSize(environment))
+ .isEqualTo(ModifyApplicationHandlerHelper.DEFAULT_MAX_UPLOAD_SIZE);
+ }
+
+ @Test
+ void resolveDefaultMaxSize_ignoresBlankConfig() {
+ CdsEnvironment environment = mock(CdsEnvironment.class);
+ when(environment.getProperty("cds.attachments.maxUploadSize", String.class, null))
+ .thenReturn(" ");
+
+ assertThat(Registration.resolveDefaultMaxSize(environment))
+ .isEqualTo(ModifyApplicationHandlerHelper.DEFAULT_MAX_UPLOAD_SIZE);
+ }
+
+ @Test
+ void resolveDefaultMaxSize_honorsConfiguredOverride() {
+ CdsEnvironment environment = mock(CdsEnvironment.class);
+ when(environment.getProperty("cds.attachments.maxUploadSize", String.class, null))
+ .thenReturn("1GB");
+
+ assertThat(Registration.resolveDefaultMaxSize(environment)).isEqualTo("1GB");
+ }
+
private void isHandlerForClassIncluded(
List