undf: assign UNDF-2026-000000874; stamp vllm-0001 patch
This commit is contained in:
parent
80b26e82b6
commit
7e717432dd
196 changed files with 835 additions and 1 deletions
|
|
@ -0,0 +1,20 @@
|
|||
# UNDF: UNDF-2026-000000871
|
||||
--- a/modules/InboundEmail/InboundEmail.php
|
||||
+++ b/modules/InboundEmail/InboundEmail.php
|
||||
@@ -1236,6 +1236,7 @@
|
||||
$r = $this->db->query($q);
|
||||
$uids = array();
|
||||
+ $uidsSet = array(); // O(1) lookup instead of O(N) in_array
|
||||
|
||||
while ($a = $this->db->fetchByAssoc($r)) {
|
||||
$uids[] = $a['imap_uid'];
|
||||
+ $uidsSet[$a['imap_uid']] = true;
|
||||
}
|
||||
@@ -1261,7 +1263,7 @@
|
||||
}
|
||||
foreach ($insert as $overview) {
|
||||
- if (in_array($overview->imap_uid, $uids)) {
|
||||
+ if (isset($uidsSet[$overview->imap_uid])) {
|
||||
// fixing bug #49543: setting 'mbox' property for the following updating of other items in this box
|
||||
if (!isset($overview->mbox)) {
|
||||
$overview->mbox = $mbox;
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# UNDF: UNDF-2026-000000872
|
||||
--- a/modules/jjwg_Maps/controller.php
|
||||
+++ b/modules/jjwg_Maps/controller.php
|
||||
@@ -938,6 +938,7 @@
|
||||
}
|
||||
}
|
||||
//var_dump($records);
|
||||
+ $recordsSet = !empty($records) ? array_flip($records) : array(); // O(1) lookup
|
||||
|
||||
// Find the Items to Display
|
||||
// Assume there is no address at 0,0; it's in the Atlantic Ocean!
|
||||
@@ -959,10 +960,10 @@
|
||||
while ($display = $this->bean->db->fetchByAssoc($display_result)) {
|
||||
if (!empty($search_array['where'])) { // Select all records (advanced search) with where clause
|
||||
- if (in_array($display['id'], $records)) {
|
||||
+ if (isset($recordsSet[$display['id']])) {
|
||||
$this->bean->map_markers[] = $this->getMarkerData($display_module, $display, false, $mod_strings_display);
|
||||
}
|
||||
} elseif (!empty($_REQUEST['uid'])) { // Several records selected or this page selected
|
||||
- if (in_array($display['id'], $records)) {
|
||||
+ if (isset($recordsSet[$display['id']])) {
|
||||
$this->bean->map_markers[] = $this->getMarkerData($display_module, $display, false, $mod_strings_display);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# UNDF: UNDF-2026-000000873
|
||||
--- a/modules/Emails/Email.php
|
||||
+++ b/modules/Emails/Email.php
|
||||
@@ -2242,12 +2242,14 @@
|
||||
//// HANDLE EMAILS HAND-WRITTEN
|
||||
$contactRecipients = array();
|
||||
$knownEmails = array();
|
||||
+ $knownEmailsSet = array(); // O(1) lookup instead of O(N) in_array
|
||||
|
||||
foreach ($addrs_arr as $i => $v) {
|
||||
if (trim($v) == "") {
|
||||
continue;
|
||||
} // skip any "blanks" - will always have 1
|
||||
@@ -2254,8 +2256,9 @@
|
||||
preg_match("/[A-Z0-9._%-\']+@[A-Z0-9.-]+\.[A-Z]{2,}/i", (string) $v, $match);
|
||||
|
||||
|
||||
- if (!empty($match[0]) && !in_array(trim($match[0]), $knownEmails)) {
|
||||
+ if (!empty($match[0]) && !isset($knownEmailsSet[trim($match[0])])) {
|
||||
$knownEmails[] = $match[0];
|
||||
+ $knownEmailsSet[trim($match[0])] = true;
|
||||
$recipient['email'] = $match[0];
|
||||
BIN
defects/suitecrm/test/SuiteCRMCWE407Test.class
Normal file
BIN
defects/suitecrm/test/SuiteCRMCWE407Test.class
Normal file
Binary file not shown.
204
defects/suitecrm/test/SuiteCRMCWE407Test.java
Normal file
204
defects/suitecrm/test/SuiteCRMCWE407Test.java
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
import java.util.*;
|
||||
|
||||
/**
|
||||
* CWE-407 unit tests for SuiteCRM defects.
|
||||
*
|
||||
* suitecrm-0001: InboundEmail.php in_array($overview->imap_uid, $uids)
|
||||
* — O(I*U) email cache UID membership check
|
||||
* suitecrm-0002: jjwg_Maps/controller.php in_array($display['id'], $records)
|
||||
* — O(D*R) map marker record filter
|
||||
* suitecrm-0003: Email.php in_array(trim($match[0]), $knownEmails)
|
||||
* — O(N^2) email dedup accumulator
|
||||
*/
|
||||
public class SuiteCRMCWE407Test {
|
||||
|
||||
// ---- suitecrm-0001: InboundEmail UID membership ----
|
||||
|
||||
/** Unpatched: in_array on $uids array — O(I*U) */
|
||||
static int inboundEmailUnpatched(List<String> insertUids, List<String> cachedUids) {
|
||||
int updateCount = 0;
|
||||
for (String uid : insertUids) {
|
||||
if (cachedUids.contains(uid)) { // O(U) per email
|
||||
updateCount++;
|
||||
}
|
||||
}
|
||||
return updateCount;
|
||||
}
|
||||
|
||||
/** Patched: hash set for O(1) lookup — O(I+U) */
|
||||
static int inboundEmailPatched(List<String> insertUids, List<String> cachedUids) {
|
||||
Set<String> uidSet = new HashSet<>(cachedUids); // O(U) once
|
||||
int updateCount = 0;
|
||||
for (String uid : insertUids) {
|
||||
if (uidSet.contains(uid)) { // O(1) per email
|
||||
updateCount++;
|
||||
}
|
||||
}
|
||||
return updateCount;
|
||||
}
|
||||
|
||||
// ---- suitecrm-0002: jjwg_Maps record filter ----
|
||||
|
||||
/** Unpatched: in_array on $records — O(D*R) */
|
||||
static int mapMarkersUnpatched(List<String> displayIds, List<String> records) {
|
||||
int markers = 0;
|
||||
for (String id : displayIds) {
|
||||
if (records.contains(id)) { // O(R) per display
|
||||
markers++;
|
||||
}
|
||||
}
|
||||
return markers;
|
||||
}
|
||||
|
||||
/** Patched: array_flip for O(1) lookup — O(D+R) */
|
||||
static int mapMarkersPatched(List<String> displayIds, List<String> records) {
|
||||
Set<String> recordsSet = new HashSet<>(records); // O(R) once
|
||||
int markers = 0;
|
||||
for (String id : displayIds) {
|
||||
if (recordsSet.contains(id)) { // O(1) per display
|
||||
markers++;
|
||||
}
|
||||
}
|
||||
return markers;
|
||||
}
|
||||
|
||||
// ---- suitecrm-0003: Email knownEmails dedup ----
|
||||
|
||||
/** Unpatched: in_array on growing knownEmails — O(N^2) */
|
||||
static int emailDedupUnpatched(List<String> addresses) {
|
||||
List<String> knownEmails = new ArrayList<>();
|
||||
int unique = 0;
|
||||
for (String addr : addresses) {
|
||||
if (!knownEmails.contains(addr)) { // O(N) scan
|
||||
knownEmails.add(addr);
|
||||
unique++;
|
||||
}
|
||||
}
|
||||
return unique;
|
||||
}
|
||||
|
||||
/** Patched: hash set for O(1) lookup — O(N) total */
|
||||
static int emailDedupPatched(List<String> addresses) {
|
||||
Set<String> knownEmailsSet = new HashSet<>();
|
||||
int unique = 0;
|
||||
for (String addr : addresses) {
|
||||
if (!knownEmailsSet.contains(addr)) { // O(1) lookup
|
||||
knownEmailsSet.add(addr);
|
||||
unique++;
|
||||
}
|
||||
}
|
||||
return unique;
|
||||
}
|
||||
|
||||
// ---- Test harness ----
|
||||
|
||||
static void testSuiteCRM0001() {
|
||||
System.out.println("=== suitecrm-0001: InboundEmail UID membership ===");
|
||||
int U = 10000; // cached UIDs in mailbox
|
||||
int I = 500; // new emails to insert
|
||||
|
||||
List<String> cachedUids = new ArrayList<>(U);
|
||||
for (int i = 0; i < U; i++) {
|
||||
cachedUids.add("uid_" + i);
|
||||
}
|
||||
List<String> insertUids = new ArrayList<>(I);
|
||||
for (int i = U - I / 2; i < U + I / 2; i++) {
|
||||
insertUids.add("uid_" + i);
|
||||
}
|
||||
|
||||
// Warmup
|
||||
inboundEmailPatched(insertUids, cachedUids);
|
||||
|
||||
long t0 = System.nanoTime();
|
||||
int r1 = inboundEmailUnpatched(insertUids, cachedUids);
|
||||
long unpatched = System.nanoTime() - t0;
|
||||
|
||||
t0 = System.nanoTime();
|
||||
int r2 = inboundEmailPatched(insertUids, cachedUids);
|
||||
long patched = System.nanoTime() - t0;
|
||||
|
||||
assert r1 == r2 : "Result mismatch";
|
||||
assert r1 == I / 2 : "Expected " + (I / 2) + " updates, got " + r1;
|
||||
|
||||
double ratio = (double) unpatched / patched;
|
||||
System.out.printf(" U=%d I=%d unpatched=%dms patched=%dms ratio=%.1fx%n",
|
||||
U, I, unpatched / 1_000_000, patched / 1_000_000, ratio);
|
||||
assert ratio > 5.0 : "Expected >5x ratio, got " + ratio;
|
||||
System.out.println(" PASS");
|
||||
}
|
||||
|
||||
static void testSuiteCRM0002() {
|
||||
System.out.println("=== suitecrm-0002: jjwg_Maps record filter ===");
|
||||
int D = 5000; // display results
|
||||
int R = 3000; // selected records
|
||||
|
||||
List<String> displayIds = new ArrayList<>(D);
|
||||
for (int i = 0; i < D; i++) {
|
||||
displayIds.add("id_" + i);
|
||||
}
|
||||
List<String> records = new ArrayList<>(R);
|
||||
for (int i = 0; i < R; i++) {
|
||||
records.add("id_" + (i * 2)); // even IDs only
|
||||
}
|
||||
|
||||
// Warmup
|
||||
mapMarkersPatched(displayIds, records);
|
||||
|
||||
long t0 = System.nanoTime();
|
||||
int r1 = mapMarkersUnpatched(displayIds, records);
|
||||
long unpatched = System.nanoTime() - t0;
|
||||
|
||||
t0 = System.nanoTime();
|
||||
int r2 = mapMarkersPatched(displayIds, records);
|
||||
long patched = System.nanoTime() - t0;
|
||||
|
||||
assert r1 == r2 : "Result mismatch";
|
||||
|
||||
double ratio = (double) unpatched / patched;
|
||||
System.out.printf(" D=%d R=%d unpatched=%dms patched=%dms ratio=%.1fx%n",
|
||||
D, R, unpatched / 1_000_000, patched / 1_000_000, ratio);
|
||||
assert ratio > 5.0 : "Expected >5x ratio, got " + ratio;
|
||||
System.out.println(" PASS");
|
||||
}
|
||||
|
||||
static void testSuiteCRM0003() {
|
||||
System.out.println("=== suitecrm-0003: Email knownEmails dedup ===");
|
||||
int N = 10000; // email addresses in mass send
|
||||
|
||||
List<String> addresses = new ArrayList<>(N);
|
||||
for (int i = 0; i < N; i++) {
|
||||
addresses.add("user" + i + "@example.com");
|
||||
}
|
||||
// Add duplicates
|
||||
for (int i = 0; i < N / 5; i++) {
|
||||
addresses.add("user" + i + "@example.com");
|
||||
}
|
||||
|
||||
// Warmup
|
||||
emailDedupPatched(addresses);
|
||||
|
||||
long t0 = System.nanoTime();
|
||||
int r1 = emailDedupUnpatched(addresses);
|
||||
long unpatched = System.nanoTime() - t0;
|
||||
|
||||
t0 = System.nanoTime();
|
||||
int r2 = emailDedupPatched(addresses);
|
||||
long patched = System.nanoTime() - t0;
|
||||
|
||||
assert r1 == r2 : "Result mismatch";
|
||||
assert r1 == N : "Expected " + N + " unique, got " + r1;
|
||||
|
||||
double ratio = (double) unpatched / patched;
|
||||
System.out.printf(" N=%d unpatched=%dms patched=%dms ratio=%.1fx%n",
|
||||
N, unpatched / 1_000_000, patched / 1_000_000, ratio);
|
||||
assert ratio > 5.0 : "Expected >5x ratio, got " + ratio;
|
||||
System.out.println(" PASS");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
testSuiteCRM0001();
|
||||
testSuiteCRM0002();
|
||||
testSuiteCRM0003();
|
||||
System.out.println("\nAll 3 SuiteCRM CWE-407 tests PASSED.");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue