Copilot commented on code in PR #3459:
URL: https://github.com/apache/fluss/pull/3459#discussion_r3400620990


##########
fluss-server/src/main/java/org/apache/fluss/server/utils/ServerRpcMessageUtils.java:
##########
@@ -355,17 +359,33 @@ public static List<TableChange> 
toAddColumns(List<PbAddColumn> addColumns) {
         return addColumns.stream()
                 .filter(Objects::nonNull)
                 .map(
-                        pbAddColumn ->
-                                TableChange.addColumn(
-                                        pbAddColumn.getColumnName(),
-                                        JsonSerdeUtils.readValue(
-                                                pbAddColumn.getDataTypeJson(),
-                                                DataTypeJsonSerde.INSTANCE),
-                                        pbAddColumn.hasComment() ? 
pbAddColumn.getComment() : null,
-                                        
toColumnPosition(pbAddColumn.getColumnPositionType())))
+                        pbAddColumn -> {
+                            AggFunction aggFunction =
+                                    pbAddColumn.hasSerializedAggFunction()
+                                            ? deserializeAggFunction(
+                                                    
pbAddColumn.getSerializedAggFunction())
+                                            : null;
+                            return TableChange.addColumn(
+                                    pbAddColumn.getColumnName(),
+                                    JsonSerdeUtils.readValue(
+                                            pbAddColumn.getDataTypeJson(),
+                                            DataTypeJsonSerde.INSTANCE),
+                                    pbAddColumn.hasComment() ? 
pbAddColumn.getComment() : null,
+                                    
toColumnPosition(pbAddColumn.getColumnPositionType()),
+                                    aggFunction);
+                        })
                 .collect(Collectors.toList());
     }
 
+    private static AggFunction deserializeAggFunction(byte[] 
serializedAggFunction) {
+        try {
+            return InstantiationUtils.deserializeObject(
+                    serializedAggFunction, AggFunction.class.getClassLoader());
+        } catch (IOException | ClassNotFoundException e) {
+            throw new FlussRuntimeException("Failed to deserialize aggregation 
function.", e);
+        }
+    }

Review Comment:
   Deserializing an arbitrary `byte[]` received over RPC into a Java object is 
a high-risk pattern (gadget-based deserialization vulnerabilities) and is 
sensitive to version/classloader compatibility. Prefer a safe, structured wire 
format for aggregation functions (e.g., protobuf fields like function type + 
parameters) or enforce strict class allowlisting / object input filtering 
during deserialization (and reject any unexpected classes) so untrusted clients 
cannot trigger unsafe deserialization.



##########
fluss-server/src/main/java/org/apache/fluss/server/utils/TableDescriptorValidation.java:
##########
@@ -323,6 +323,9 @@ private static void checkArrowCompression(Configuration 
tableConf) {
     private static void checkMergeEngine(
             Configuration tableConf, boolean hasPrimaryKey, Schema schema) {
         MergeEngineType mergeEngine = 
tableConf.get(ConfigOptions.TABLE_MERGE_ENGINE);
+        if (mergeEngine != MergeEngineType.AGGREGATION) {
+            validateNoAggregationFunctions(schema);
+        }

Review Comment:
   This condition will also run when `mergeEngine` is `null` (since `null != 
MergeEngineType.AGGREGATION`), which can incorrectly reject schemas containing 
aggregation functions even when the merge engine is unset/implicit. Consider 
guarding the check with `mergeEngine != null && mergeEngine != 
MergeEngineType.AGGREGATION`, or otherwise aligning this validation with the 
intended default merge-engine behavior.



##########
fluss-server/src/main/java/org/apache/fluss/server/utils/TableDescriptorValidation.java:
##########
@@ -377,6 +380,20 @@ private static void checkMergeEngine(
         }
     }
 
+    /** Validates that the schema doesn't contain any aggregation functions. */
+    public static void validateNoAggregationFunctions(Schema schema) {

Review Comment:
   Exposing this method as `public` broadens the API surface of 
`TableDescriptorValidation` (even if it's in a server module) and makes it 
harder to change later. If this is intended only for server-internal reuse 
during schema alter, consider moving these validators into a dedicated internal 
validator class (or annotating as internal if the project has such an 
annotation) and/or minimizing visibility where possible to avoid treating it as 
a supported external API.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to