From fdfd7cdd81c4b7cb1117baa5c66606e4298f8c35 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 25 Jun 2024 16:23:25 +0100 Subject: [PATCH] [ML] Fixing issue with empty object creation (#186821) Using `Object.create(null)` when creating objects for the anomaly results table. (cherry picked from commit 8e76b0b113089c793e4dba77610f90540ec9b8da) --- .../build_anomaly_table_items.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/ml/server/models/results_service/build_anomaly_table_items.js b/x-pack/plugins/ml/server/models/results_service/build_anomaly_table_items.js index 380d5e4a881aa..d3f4ef77d19f4 100644 --- a/x-pack/plugins/ml/server/models/results_service/build_anomaly_table_items.js +++ b/x-pack/plugins/ml/server/models/results_service/build_anomaly_table_items.js @@ -125,7 +125,7 @@ function aggregateAnomalies(anomalyRecords, interval, dateFormatTz) { return []; } - const aggregatedData = {}; + const aggregatedData = Object.create(null); anomalyRecords.forEach((record) => { // Use moment.js to get start of interval. const roundedTime = @@ -133,27 +133,32 @@ function aggregateAnomalies(anomalyRecords, interval, dateFormatTz) { ? moment(record.timestamp).tz(dateFormatTz).startOf(interval).valueOf() : moment(record.timestamp).startOf(interval).valueOf(); if (aggregatedData[roundedTime] === undefined) { - aggregatedData[roundedTime] = {}; + aggregatedData[roundedTime] = Object.create(null); } // Aggregate by job, then detectorIndex. const jobId = record.job_id; const jobsAtTime = aggregatedData[roundedTime]; - if (jobsAtTime[jobId] === undefined) { - jobsAtTime[jobId] = {}; + if (jobsAtTime[jobId] === undefined || Object.hasOwn(jobsAtTime, jobId) === false) { + jobsAtTime[jobId] = Object.create(null); } // Aggregate by detector - default to function_description if no description available. const detectorIndex = record.detector_index; + if (typeof detectorIndex !== 'number') { + return; + } const detectorsForJob = jobsAtTime[jobId]; if (detectorsForJob[detectorIndex] === undefined) { - detectorsForJob[detectorIndex] = {}; + detectorsForJob[detectorIndex] = Object.create(null); } // Now add an object for the anomaly with the highest anomaly score per entity. // For the choice of entity, look in order for byField, overField, partitionField. // If no by/over/partition, default to an empty String. - const entitiesForDetector = detectorsForJob[detectorIndex]; + const entitiesForDetector = Object.hasOwn(detectorsForJob, detectorIndex) + ? detectorsForJob[detectorIndex] + : Object.create(null); // TODO - are we worried about different byFields having the same // value e.g. host=server1 and machine=server1? @@ -163,7 +168,7 @@ function aggregateAnomalies(anomalyRecords, interval, dateFormatTz) { } if (entitiesForDetector[entity] === undefined) { entitiesForDetector[entity] = record; - } else { + } else if (Object.hasOwn(entitiesForDetector, entity)) { if (record.record_score > entitiesForDetector[entity].record_score) { entitiesForDetector[entity] = record; }