### 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)

return recursive_equal(p_dictionary, 0);
}
bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
	return !recursive_equal(p_dictionary, 0);
}
bool Dictionary::recursive_equal(const Dictionary &p_dictionary, int recursion_count) const {
	
	if (_p == p_dictionary._p) {
		return true;
	}
	if (_p->variant_map.size() != p_dictionary._p->variant_map.size()) {
		return false;
	}
	
	if (recursion_count > MAX_RECURSION) {
		ERR_PRINT("Max recursion reached");
		return true;
	}
	recursion_count++;
	for (const KeyValue<Variant, Variant> &this_E : _p->variant_map) {
		HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator other_E(p_dictionary._p->variant_map.find(this_E.key));
		if (!other_E || !this_E.value.hash_compare(other_E->value, recursion_count)) {
			return false;
		}
	}
	return true;
}
void Dictionary::_ref(const Dictionary &p_from) const {