Skip to content

Uninitialized ivars are possible in JSON type hierarchy with explicit constructor in subclass #16729

@jgaskins

Description

@jgaskins

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").type

There 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:bugA bug in the code. Does not apply to documentation, specs, etc.topic:compiler:semantic

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions