Skip to content

TBFSObjectIDRefPair missing abstract method implementations causes runtime crash #39

@bero

Description

@bero

Problem

The TBFSObjectIDRefPair class in Source/FreestandingValueSpace/Core/BoldFreeStandingValues.pas is missing implementations for two abstract methods declared in its parent class TBFSObjectIDRefAbstract:

  • GetStringRepresentation(representation: integer): String
  • GetContentAsString: String

Class Hierarchy

TBFSObjectIDRefAbstract (lines 396-407)
├── GetStringRepresentation: virtual; abstract;  ← declares abstract
├── GetContentAsString: virtual; abstract;       ← declares abstract
│
├── TBFSObjectIDRef (lines 410-426)
│   └── Implements both methods correctly ✓
│
└── TBFSObjectIDRefPair (lines 428-446)
    └── MISSING implementations ✗

Impact

Runtime "Abstract Error" crash when any code attempts to call:

  • TBFSObjectIDRefPair.GetStringRepresentation()
  • TBFSObjectIDRefPair.GetContentAsString
  • Any interface method that relies on IBoldStringRepresentable for this class

This class implements IBoldStringRepresentable interface (line 429), which requires these methods. When the methods are accessed through the interface, Delphi calls the abstract methods which immediately raises an EAbstractError exception at runtime.

Why Delphi Compiles This

Delphi only emits a warning (W1020: "Constructing instance containing abstract method") for abstract method violations, not an error. This allows the code to compile but crash at runtime.

Fix

Add the missing method implementations to TBFSObjectIDRefPair:

In class declaration (after line 439):

function GetStringRepresentation(representation: integer): String; override;
function GetContentAsString: String; override;

In implementation section (after GetId2 around line 1326):

function TBFSObjectIDRefPair.GetStringRepresentation(representation: integer): String;
begin
  if Assigned(fObjectIds) then
    Result := fObjectIds.CommaSeparatedIdList
  else
    Result := '<nil>, <nil>';
end;

function TBFSObjectIDRefPair.GetContentAsString: String;
begin
  Result := GetStringRepresentation(brDefault);
end;

This follows the same pattern as:

  1. TBFSObjectIDRef.GetStringRepresentation (uses ObjectId.AsString)
  2. TBFSObjectIdListRef.GetStringRepresentation (uses CommaSeparatedIdList)

Severity

High - This is a latent crash bug. Any code path that accesses the string representation of TBFSObjectIDRefPair will crash the application with an EAbstractError.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions