Repository navigation
fix(dx8wrapper): Prevent undefined behavior when converting Vector4 colors - #3655
CryoTheRenegade wants to merge 2 commits into
Conversation
…ctor3 cast DX8Wrapper::Convert_Color(const Vector4&) and Convert_Color_Clamp read the RGB part of a Vector4 through a Vector3 reference. On VC6, the inline assembly that converts the color now lives in Convert_Color_RGB, which takes a pointer to the red, green and blue floats. Both Convert_Color overloads pass &color.X, so the Vector4 overload doesn't copy the color into a Vector3 temporary. Other compilers build a Vector3 from X, Y and Z. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… inline assembly helper Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. WalkthroughBoth ChangesVector4 color conversion
Estimated code review effort: 1 (Trivial) | ~5 minutes Change: Bug fix Possibly related PRs
Suggested reviewers: Merge Risk:
|
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
[Medium impact] This PR appears safe to merge.
|
Follow-up to #3651, from xezon's "Are there more of these?" on #3580.
DX8Wrapper::Convert_Color(const Vector4&)andConvert_Color_Clamppass the color to theVector3overload withreinterpret_cast<const Vector3&>(color). AVector4is not aVector3, so reading it through that reference is undefined behavior, the same problem as #3521.Convert_Color(const Vector4&)now builds aVector3from the first three components, andConvert_Color_Clampcalls it after clamping:WWINLINE unsigned int DX8Wrapper::Convert_Color(const Vector4& color) { - return Convert_Color(reinterpret_cast<const Vector3&>(color),color[3]); + return Convert_Color(Vector3(color.X,color.Y,color.Z),color.W); } ... - return Convert_Color(reinterpret_cast<const Vector3&>(clamped_color),clamped_color[3]); + return Convert_Color(clamped_color);Evidence
dynamesh.cpp,pointgr.cpp,streakRender.cpp,W3DScorch.cppandW3DTerrainParticles.cpp) against a build ofmain, for both games. In every changed function, the float arithmetic and the call targets are the same as onmain.DynamicMeshClass::Change_Vertex_Color,PointGroupClass::Render,PointGroupClass::RenderVolumeParticleandStreakRendererClass::RenderStreakchanged only in register allocation and stack offsets.W3DScorch::updateScorches, theW3DTerrainParticlesconstructor andW3DTerrainParticles::rendernow copy the three floats into theVector3temporary (threefld/fstppairs) before the inline assembly converts the color. The other three files are unchanged.AI Disclosure
Claude Opus 5.5 was used to aid in implementation and to compare the disassembly.