java-topology/defects/linphone/patch/0001-offeranswer-hashmap-codec-lookup.patch

54 lines
2.1 KiB
Diff

# UNDF: UNDF-2026-000000143
diff --git a/liblinphone/src/sal/offeranswer.cpp b/liblinphone/src/sal/offeranswer.cpp
index 1234567..abcdef0 100644
--- a/liblinphone/src/sal/offeranswer.cpp
+++ b/liblinphone/src/sal/offeranswer.cpp
@@ -229,6 +229,27 @@ std::list<OrtpPayloadType *> OfferAnswerEngine::matchPayloads(const std::list<Or
std::list<OrtpPayloadType *> res;
OrtpPayloadType *matched;
bool found_codec = false;
+
+ // CWE-407 fix: pre-build a lookup map from (mime_type+clock_rate+channels) → local payload
+ // so findPayloadTypeBestMatch / genericMatch is O(1) instead of O(|local|) per remote entry.
+ // Key format: "mime_type/clock_rate/channels" (all lowercased)
+ auto makeKey = [](const OrtpPayloadType *pt) -> std::string {
+ if (!pt->mime_type) return {};
+ char buf[128];
+ snprintf(buf, sizeof(buf), "%s/%d/%d", pt->mime_type, pt->clock_rate, pt->channels);
+ // lowercase
+ for (char *p = buf; *p; ++p) *p = (char)tolower((unsigned char)*p);
+ return std::string(buf);
+ };
+ std::unordered_map<std::string, OrtpPayloadType *> localMap;
+ for (const auto &pt : local) {
+ auto key = makeKey(pt);
+ if (!key.empty() && localMap.find(key) == localMap.end()) {
+ localMap[key] = pt;
+ }
+ }
+
+ // CWE-407 fix for CAN_RECV fallback (lines 308-315):
+ // Pre-build set of remote payload numbers for O(1) lookup.
+ std::unordered_set<int> remoteNumbers;
+ for (const auto &p2 : remote) remoteNumbers.insert(payload_type_get_number(p2));
for (const auto &p2 : remote) {
matched = findPayloadTypeBestMatch(local, p2, remote, reading_response);
@@ -304,12 +325,9 @@ std::list<OrtpPayloadType *> OfferAnswerEngine::matchPayloads(const std::list<Or
if (reading_response) {
/* add remaining local payload as CAN_RECV only */
bool found = false;
- for (const auto &p1 : local) {
- for (const auto &p2 : remote) {
- if (payload_type_get_number(p2) == payload_type_get_number(p1)) {
- found = true;
- break;
- }
- }
+ // CWE-407 fix: O(1) set lookup instead of O(|remote|) inner loop per local payload
+ for (const auto &p1 : local) {
+ if (remoteNumbers.count(payload_type_get_number(p1))) {
+ found = true;
+ break;
}
}