Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various small fixes identified by cppcheck #1371

Merged
merged 15 commits into from
Nov 3, 2023
Merged

Conversation

dpogue
Copy link
Member

@dpogue dpogue commented Apr 9, 2023

Best to review this one commit at a time and I can drop any commits that people deem controversial.

This does not clear up all the issues that cppcheck found, but these were some low-hanging fruit.

@@ -411,7 +411,7 @@ void DebugMsg(const char* fmt, ...);

#if defined(_MSC_VER)
#define DEFAULT_FATAL(var) default: FATAL("No valid case for switch variable '" #var "'"); __assume(0); break;
#elif defined(__GNUC__)
#elif defined(__GNUC__) || defined(__clang__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For anyone else wondering: Clang also defines __GNUC__, but only on Unix platforms. On Windows, you need to explicitly check __clang__.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, is that accurate? I would have expected this to be more of a clang vs clang-cl distinction, not a Unix vs Windows distinction...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's what I would have expected too, but it seems to make no difference. I tested using the Clang 12 from VS 2019, and both clang and clang-cl define only __clang__ and not __GNUC__.

Copy link
Member

@zrax zrax Apr 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it might be more of an SDK thing then -- Clang from MSYS2, for example, does define __GNUC__ even on Windows, but that version would be using the MinGW SDK rather than the MSVC Windows SDK. Either way, the fix is appropriate, since Clang doesn't always define __GNUC__... It just piqued my curiosity :)

@@ -411,7 +411,7 @@ void DebugMsg(const char* fmt, ...);

#if defined(_MSC_VER)
#define DEFAULT_FATAL(var) default: FATAL("No valid case for switch variable '" #var "'"); __assume(0); break;
#elif defined(__GNUC__)
#elif defined(__GNUC__) || defined(__clang__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, is that accurate? I would have expected this to be more of a clang vs clang-cl distinction, not a Unix vs Windows distinction...

@@ -1706,7 +1706,7 @@ class plBDFCharsParser : public plBDFSectParser
{
// If we're doing data, all lines are hex values until we hit "ENDCHAR"
if( fRowsLeft == 0 )
throw;
throw false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this is suspicious... throw without any parameter will re-throw the current exception or call std::terminate if there isn't one... But what does throwing a bool accomplish? Who's catching from this call? I feel like either changing this to throw a proper exception (like std::runtime_error) or an explicit crash (like hsAssert(false)) would be better.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several other throw statements in this function that were throwing bools, so this was just making it consistent, but I'll try to investigate whether anything is actually catching these errors. Maybe hsAssert is a better option.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it appears that calls to parse the BDF contents are wrapped in a try/catch block, and catch both std::exception and non-exceptions:

catch (std::exception &e)
{
printf("Exception caught in plFont::LoadFromBDF: %s\n", e.what());
IClear();
fclose(fp);
return false;
}
catch (...)
{
IClear();
fclose( fp );
return false;
}

It seems the only place this BDF code is actually used is in plFontConverter, and freetype2 has built-in BDF support so it's unclear to me if this code is still serving any purpose or if it should be removed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this should probably throw a real std::exception for logging purposes.

break;
}
s = 1 << i;
hsAssert(i >= 0, "Invalid non-POT shadow size");
s = 1u << i;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cppcheck is still warning about i potentially being uint32_t(-1), but I think that's because hsAssert doesn't guarantee end of execution when HS_DEBUGGING is set.

@dpogue dpogue force-pushed the cppcheck branch 3 times, most recently from 498f96f to e8949ee Compare April 11, 2023 03:47
@@ -859,6 +859,11 @@ void plArmatureMod::SpawnAt(int spawnNum, double time)

void plArmatureMod::SetFollowerParticleSystemSO(plSceneObject *follower)
{
if (!follower) {
fFollowerParticleSystemSO = follower;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to set up the key reference for the new follower (see line 873), which could cause the follower to be thrown away from under us.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, follower is null

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still concerned about this. While it is true that follower is null, this seems like it's leaking the reference established on line 873. I do think it would be better to make it more obvious that fFollowerParticleSystemSO is being set to nullptr.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there is a case (albeit perhaps unused in normal gameplay) where this method gets called with nullptr, and in theory the current code will crash.

If your preference to use the existing fFollowerParticleSystemSO to remove the reference (and maybe change SetAttachedToAvatar(false) on the particle system itself?) before setting it to null?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that's correct. We'll basically want to send another plAttachMsg with plRefMsg::kOnRemove, I think.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this to send a detach message

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For future reference, I went through and verified that sending a plAttachMsg with the context kOnRemove will release the key reference. This happens in plCoordinateInterface::IDetachChild().

@Hoikas
Copy link
Member

Hoikas commented Oct 15, 2023

What is the status here?

@dpogue
Copy link
Member Author

dpogue commented Oct 16, 2023

I think this was just waiting for re-review

dpogue and others added 14 commits October 23, 2023 20:11
In theory there's no way this would ever really cause issues, but it's
easy enough to resolve by shuffling ifdefs around.
Pretty sure the intention was to filter out non-attach ref messages, but
the default case was allowing them through before the ref message check
ever ran.
There's one spot that does actually appear to call this with nullptr,
so I'm not sure how this hasn't been causing crashes...

Co-Authored-By: Adam Johnson <[email protected]>
We're already asserting that the size of the containers will fit in a
uint16_t, but this was getting flagged by CodeQL as a potential
overflow.
@Hoikas Hoikas merged commit 1c4209c into H-uru:master Nov 3, 2023
@dpogue dpogue deleted the cppcheck branch November 3, 2023 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants