-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Uninitialized ivars are possible in JSON type hierarchy with explicit constructor in subclass #16729
Description
Couldn't find this mentioned anywhere in the issue tracker, but TL;DR: The following code results in a segfault on Crystal 1.19.1 because an ivar in the parent type is uninitialized.
require "json"
abstract struct Element
include JSON::Serializable
getter type : String
end
record Text < Element, body : String
puts Text.new("asdf").typeThere is a compiler check for constructors that don't initialize all ivars that should catch this, but it seems to be missing that the constructor defined in Text doesn't set @type. I'm using the record macro to define the subclass in this example, but that's just for brevity. The segfault still happens when you define an explicit struct Text < Element with def initialize(@body).
Without the include JSON::Serializable, that constructor check catches this bug at compile time. There seems to be something about the constructor that JSON::Serializable defines, combined with the type inheritance, that the check isn't picking up.
Obviously, this segfault only gets triggered when interacting with the uninitialized ivar in the parent class, and only for a subset of types. This does not segfault if that ivar is an Int32, for example, because whatever value is in that memory will be valid. But since I'm using a String, it dereferences an uninitialized pointer, which is unlikely to contain anything useful, which triggers a segfault.