Python: fix heap-use-after-free in MapIterator after map.clear() (#27257)

## Bug

`Clear()` in `map_container.cc` (line 294-302) calls
`reflection->ClearField()` which destroys all underlying map nodes via
`ClearTable(reset=true)`, but does not increment `self->version`.

All other mutators (ScalarMapSetItem, MessageMapSetItem, MergeFrom, etc.)
increment `self->version` after mutation. `IterNext()` relies on version
mismatch to detect concurrent modification and raise `RuntimeError`.
Without the version bump, a live iterator proceeds to dereference the
freed `NodeBase*` via `SetMapIteratorValue` → `UntypedMapIterator::PlusPlus`.

**ASAN confirmed:** heap-use-after-free, READ size 8 at
`UntypedMapIterator::PlusPlus` (map.h:599), freed by `ClearTable`
(map.h:345), allocated by `ScalarMapSetItem` (map_container.cc:416).

## Fix

Add `self->version++` after `ClearField` in `Clear()`, matching every
other mutator in the same file.

## Reproducer

```python
msg = M()  # proto3 with map<string, int32> mp
for k in ("a","b","c","d"): msg.mp[k] = 1
it = iter(msg.mp)
next(it)
msg.mp.clear()   # frees nodes, version NOT bumped
next(it)         # heap-use-after-free
```

Closes #27257

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/27257 from vhullto:fix/python-map-clear-uaf fb352251107932570e8ec5ba293b18e8d74521b6
PiperOrigin-RevId: 939482747
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index 4ae6ae8..7c10d78 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -3041,6 +3041,19 @@
     self.assertEqual(keys, int32_foreign_keys)
     self.assertEqual(keys, list(msg.map_int32_foreign_message.keys()))
 
+  def test_map_clear_during_iteration(self):
+    # Regression: clear() did not bump iterator version, causing UAF.
+    msg = map_unittest_pb2.TestMap()
+    msg.map_string_string['a'] = '1'
+    msg.map_string_string['b'] = '2'
+    msg.map_string_string['c'] = '3'
+    msg.map_string_string['d'] = '4'
+
+    it = iter(msg.map_string_string)
+    next(it)
+    msg.map_string_string.clear()
+    with self.assertRaises(RuntimeError):
+      next(it)
   def testSubmessageMap(self):
     msg = map_unittest_pb2.TestMap()
 
diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc
index f88171e..4b6b71e 100644
--- a/python/google/protobuf/pyext/map_container.cc
+++ b/python/google/protobuf/pyext/map_container.cc
@@ -285,6 +285,7 @@
   const Reflection* reflection = message->GetReflection();
 
   reflection->ClearField(message, self->parent_field_descriptor);
+  self->version++;
 
   Py_RETURN_NONE;
 }