### Godot version

4.0 (c1128e911ccd6f1e8c35646df804d894652a58f1)

### System information

Arch Linux

### Issue description

Read-only dictionaries can still have new keys added. The value for the new key isn't set (it is kept `null`).

This is caused by `Dictionary::operator[]` not checking if the key exists when it is read only mode. Accessing a key in the underlying HashMap will create if it does not exist. The actual value isn't set because it only returns a dummy reference.

### Steps to reproduce

Run the following snippet:

```gdscript
var dict = {}
dict.make_read_only()
prints("dict", dict) # {}
dict.foo = "hi"
prints("dict", dict) # { "foo": <null> }
```

### Minimal reproduction project

[DictReadOnlyAddKey.zip](https://github.com/godotengine/godot/files/10943387/DictReadOnlyAddKey.zip)

if (unlikely(_p->read_only)) {
		if (p_key.get_type() == Variant::STRING_NAME) {
			const StringName *sn = VariantInternal::get_string_name(&p_key);
			*_p->read_only = _p->variant_map[sn->operator String()];
		} else {
			*_p->read_only = _p->variant_map[p_key];
		}
		return *_p->read_only;
	} else {
		if (p_key.get_type() == Variant::STRING_NAME) {
			const StringName *sn = VariantInternal::get_string_name(&p_key);
			return _p->variant_map[sn->operator String()];
		} else {
			return _p->variant_map[p_key];
		}
	}
}
const Variant &Dictionary::operator[](const Variant &p_key) const {
	
	return _p->variant_map[p_key];
}
const Variant *Dictionary::getptr(const Variant &p_key) const {
	HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator E(_p->variant_map.find(p_key));
	if (!E) {
		return nullptr;
	}
	return &E->value;
}
Variant *Dictionary::getptr(const Variant &p_key) {