Skip to content

Commit 0bb6a8b

Browse files
committed
Avoid racing ruby_encoding_index with base index
Previously when we copied base_encoding on top of the encoding, other threads could briefly see the name and ruby_encoding_index of the base encoding.
1 parent 71fa980 commit 0bb6a8b

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

encoding.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,14 +375,20 @@ enc_register_at(struct enc_table *enc_table, int index, const char *name, rb_enc
375375
encoding = xmalloc(sizeof(rb_encoding));
376376
}
377377

378+
rb_raw_encoding tmp_encoding;
378379
if (base_encoding) {
379-
*encoding = *base_encoding;
380+
tmp_encoding = *base_encoding;
380381
}
381382
else {
382-
memset(encoding, 0, sizeof(*ent->enc));
383+
memset(&tmp_encoding, 0, sizeof(*ent->enc));
383384
}
384-
encoding->name = name;
385-
encoding->ruby_encoding_index = index;
385+
tmp_encoding.name = name;
386+
tmp_encoding.ruby_encoding_index = index;
387+
388+
// FIXME: If encoding already existed, it may be concurrently accessed
389+
// It's technically invalid to write to this memory as it's read, but as all
390+
// values are set up it _probably_ works.
391+
*encoding = tmp_encoding;
386392
ent->enc = encoding;
387393
st_insert(enc_table->names, (st_data_t)name, (st_data_t)index);
388394

0 commit comments

Comments
 (0)