diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md
index 3d510115d..62298a7a3 100644
--- a/trunk/doc/CHANGELOG.md
+++ b/trunk/doc/CHANGELOG.md
@@ -7,6 +7,7 @@ The changelog for SRS.
## SRS 6.0 Changelog
+* v6.0, 2025-10-21, Merge [#4535](https://github.com/ossrs/srs/issues/4535): Bridge: Fix heap-use-after-free in SrsCompositeBridge iterator. v6.0.183 (#4535)
* v6.0, 2025-10-17, Merge [#4534](https://github.com/ossrs/srs/pull/4534): HLS: Fix a iterator bug in hls_ctx cleanup function. v6.0.182 (#4534)
* v6.0, 2025-10-14, Disable sanitizer by default to fix memory leak. (#4364) v6.0.181
* v6.0, 2025-10-01, SRT: Support configurable default_streamid option. v6.0.180
diff --git a/trunk/src/app/srs_app_stream_bridge.cpp b/trunk/src/app/srs_app_stream_bridge.cpp
index de2915d92..9b921e842 100644
--- a/trunk/src/app/srs_app_stream_bridge.cpp
+++ b/trunk/src/app/srs_app_stream_bridge.cpp
@@ -173,7 +173,10 @@ srs_error_t SrsCompositeBridge::initialize(SrsRequest* r)
{
srs_error_t err = srs_success;
- for (vector::iterator it = bridges_.begin(); it != bridges_.end(); ++it) {
+ // Make a copy of bridges to avoid iterator invalidation if bridges_ is modified during iteration.
+ // See https://github.com/ossrs/srs/issues/4535
+ vector bridges_copy = bridges_;
+ for (vector::iterator it = bridges_copy.begin(); it != bridges_copy.end(); ++it) {
ISrsStreamBridge* bridge = *it;
if ((err = bridge->initialize(r)) != srs_success) {
return err;
@@ -187,7 +190,10 @@ srs_error_t SrsCompositeBridge::on_publish()
{
srs_error_t err = srs_success;
- for (vector::iterator it = bridges_.begin(); it != bridges_.end(); ++it) {
+ // Make a copy of bridges to avoid iterator invalidation if bridges_ is modified during iteration.
+ // See https://github.com/ossrs/srs/issues/4535
+ vector bridges_copy = bridges_;
+ for (vector::iterator it = bridges_copy.begin(); it != bridges_copy.end(); ++it) {
ISrsStreamBridge* bridge = *it;
if ((err = bridge->on_publish()) != srs_success) {
return err;
@@ -199,7 +205,10 @@ srs_error_t SrsCompositeBridge::on_publish()
void SrsCompositeBridge::on_unpublish()
{
- for (vector::iterator it = bridges_.begin(); it != bridges_.end(); ++it) {
+ // Make a copy of bridges to avoid iterator invalidation if bridges_ is modified during iteration.
+ // See https://github.com/ossrs/srs/issues/4535
+ vector bridges_copy = bridges_;
+ for (vector::iterator it = bridges_copy.begin(); it != bridges_copy.end(); ++it) {
ISrsStreamBridge* bridge = *it;
bridge->on_unpublish();
}
diff --git a/trunk/src/core/srs_core_version6.hpp b/trunk/src/core/srs_core_version6.hpp
index 1f34e7481..70d1a7a39 100644
--- a/trunk/src/core/srs_core_version6.hpp
+++ b/trunk/src/core/srs_core_version6.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 6
#define VERSION_MINOR 0
-#define VERSION_REVISION 182
+#define VERSION_REVISION 183
#endif