[Addressed] PSprites with an ID of 0 can be created infinitely

Bugs that have been investigated and resolved somehow.

Moderator: GZDoom Developers

Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.

PSprites with an ID of 0 can be created infinitely

Postby Boondorl » Mon Jan 10, 2022 2:41 pm

As the title suggests, there's currently an oversight with PSprites that are assigned an ID of 0. While PSprites with that ID can be created freely via GetPSprite(), the issue arises with FindPSprite(). If an argument of 0 is passed it will always return null. This forces GetPSprite() to create a new PSprite every time. Normally PSprites do a duplicate check on creation to make sure copies aren't created, but this check is specifically ignored if the ID is 0. This means any time GetPSprite() with an argument of 0 is called, a new PSprite will be created. This can be verified in-game:

Code: Select allExpand view
class CustomActor : Actor
{
    override void PostBeginPlay()
    {
        super.PostBeginPlay();

        players[consoleplayer].GetPSprite(0);
        players[consoleplayer].GetPSprite(0);
        players[consoleplayer].GetPSprite(0);
        players[consoleplayer].GetPSprite(0);
        players[consoleplayer].GetPSprite(0);

        let psp = players[consoleplayer].psprites;
        while (psp)
        {
            if (psp.id == 0)
            {
                console.printf("PSprite with id 0 exists");
                if (!players[consoleplayer].FindPSprite(0))
                    console.printf("Cannot find layer 0 despite existing");
            }

            psp = psp.next;
        }
    }
}

Summon the actor via the console and this code will print 5 times. Tested on the latest GZDoom build (4.7.1).
User avatar
Boondorl
 
Joined: 11 Jul 2018

Re: PSprites with an ID of 0 can be created infinitely

Postby Graf Zahl » Tue Apr 12, 2022 4:10 am

ID 0 is considered special, the use case described here is simply undefined. 0 is treated in several places as "use the caller's id", so it cannot be handed out to user data without breaking stuff. All I can do is to unconditionally return null when this function is being called with 0.

This all is the result of a design flaw in the original implementation that did not even consider the idea of failure, so even for invalid IDs it returned something. This was later addressed, but this case overlooked.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
 
Joined: 19 Jul 2003
Location: Germany


Return to Closed Bugs

Who is online

Users browsing this forum: No registered users and 0 guests