codeant-ai-for-open-source[bot] commented on code in PR #37176:
URL: https://github.com/apache/superset/pull/37176#discussion_r2695382414


##########
superset-frontend/src/dashboard/components/nativeFilters/state.ts:
##########
@@ -96,8 +100,16 @@ const selectChartCustomizationConfiguration = 
createSelector(
       state.dashboardInfo.metadata?.chart_customization_config || EMPTY_ARRAY,
     selectDashboardChartIds,

Review Comment:
   **Suggestion:** The selector accesses `state.dashboardInfo.metadata` without 
checking whether `state.dashboardInfo` exists; if `dashboardInfo` is undefined 
this will throw at runtime. Add optional chaining on `dashboardInfo` so the 
selector safely falls back to `EMPTY_ARRAY` when `dashboardInfo` is not 
present. [null pointer]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Dashboard render crashes on missing dashboardInfo.
   - ❌ Chart customizations sidebar fails to mount.
   - ⚠️ Unit tests mocking partial store may fail.
   ```
   </details>
   
   ```suggestion
           state.dashboardInfo?.metadata?.chart_customization_config || 
EMPTY_ARRAY,
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open the dashboard UI component that uses chart customizations which calls
   useChartCustomizationConfiguration (see useChartCustomizationConfiguration at
   superset-frontend/src/dashboard/components/nativeFilters/state.ts:127).
   
   2. During initial render the selector selectChartCustomizationConfiguration 
is executed
   (defined at 
superset-frontend/src/dashboard/components/nativeFilters/state.ts:100-101).
   
   3. If Redux state has no dashboardInfo key (state.dashboardInfo === 
undefined) the
   expression at 
superset-frontend/src/dashboard/components/nativeFilters/state.ts:101
   attempts to read `.metadata` on undefined and throws a TypeError.
   
   4. Reproduce in tests by mocking react-redux useSelector to return a store 
object without
   dashboardInfo and rendering any component that calls 
useChartCustomizationConfiguration;
   the component render will throw at the selector line shown above.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/dashboard/components/nativeFilters/state.ts
   **Line:** 101:101
   **Comment:**
        *Null Pointer: The selector accesses `state.dashboardInfo.metadata` 
without checking whether `state.dashboardInfo` exists; if `dashboardInfo` is 
undefined this will throw at runtime. Add optional chaining on `dashboardInfo` 
so the selector safely falls back to `EMPTY_ARRAY` when `dashboardInfo` is not 
present.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



##########
superset-frontend/src/dataMask/reducer.ts:
##########
@@ -216,9 +220,17 @@ const dataMaskReducer = produce(
           loadedDataMask,
         );
 
-        const chartCustomizationConfig =
+        const rawChartCustomizationConfig =
           metadata?.chart_customization_config || [];
 
+        const hasLegacyFormat = rawChartCustomizationConfig.some(item =>
+          isLegacyChartCustomizationFormat(item),
+        );
+
+        const chartCustomizationConfig = hasLegacyFormat
+          ? migrateChartCustomizationArray(rawChartCustomizationConfig)
+          : (rawChartCustomizationConfig as ChartCustomization[]);

Review Comment:
   **Suggestion:** Logic bug / unsafe migration: when any legacy item exists 
the code calls `migrateChartCustomizationArray` with the entire 
`rawChartCustomizationConfig` (including already-modern items), potentially 
re-migrating or corrupting items that are already in the new format; instead, 
migrate only legacy items and preserve existing new items (while keeping 
original order). [possible bug]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Dashboard hydration can corrupt chart customization entries.
   - ❌ Sidebar chart customization shows incorrect items.
   - ⚠️ Affects dashboards with mixed-format customization arrays.
   - ⚠️ Migration may alter saved dashboard configuration.
   ```
   </details>
   
   ```suggestion
           // Migrate only legacy items and preserve non-legacy items in 
original order.
           const legacyItems = rawChartCustomizationConfig.filter(item =>
             isLegacyChartCustomizationFormat(item),
           );
           const migratedLegacyItems = legacyItems.length
             ? migrateChartCustomizationArray(legacyItems)
             : [];
           // Reconstruct final array preserving order: replace legacy entries 
with migrated ones.
           let migratedIndex = 0;
           const chartCustomizationConfig = 
rawChartCustomizationConfig.map(item =>
             isLegacyChartCustomizationFormat(item)
               ? (migratedLegacyItems[migratedIndex++] as ChartCustomization)
               : (item as ChartCustomization),
           );
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open the dashboard page that triggers dashboard hydration. The 
HYDRATE_DASHBOARD action
   is handled by the reducer at superset-frontend/src/dataMask/reducer.ts in the
   HYDRATE_DASHBOARD case (lines ~220-320). The migration code runs at lines 
223-232 in that
   file.
   
   2. Ensure the dashboard metadata returned from the backend includes
   chart_customization_config with a mix of legacy-format and 
already-modern-format items
   (the reducer reads metadata?.chart_customization_config at line 223).
   
   3. When the HYDRATE_DASHBOARD action is dispatched, the reducer evaluates 
hasLegacyFormat
   using isLegacyChartCustomizationFormat (imported from
   src/dashboard/util/migrateChartCustomization) at lines 226-228.
   
   4. Because at least one legacy item exists, the current code calls
   migrateChartCustomizationArray with the entire rawChartCustomizationConfig 
array (line
   231). If migrateChartCustomizationArray expects legacy-only inputs or 
transforms items
   generically, this will re-process modern items and can change/corrupt them. 
Observe
   unexpected/mutated chart customization entries after hydration in the 
dashboard UI
   (sidebar customizations missing or altered), originating from reducer lines 
223-232.
   
   Note: This reproduces concretely by creating a dashboard metadata payload 
containing
   mixed-format chart_customization_config and loading that dashboard so the
   HYDRATE_DASHBOARD reducer branch executes (see reducer.ts lines 220-236).
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/dataMask/reducer.ts
   **Line:** 226:232
   **Comment:**
        *Possible Bug: Logic bug / unsafe migration: when any legacy item 
exists the code calls `migrateChartCustomizationArray` with the entire 
`rawChartCustomizationConfig` (including already-modern items), potentially 
re-migrating or corrupting items that are already in the new format; instead, 
migrate only legacy items and preserve existing new items (while keeping 
original order).
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to