Page MenuHomeFeedback Tracker

EnScript.GetClassVar static array access may lead to illegal memory access
Assigned, NormalPublic

Description

If you use EnScript.GetClassVar(Class inst, string varname,int index, out void result) with static array of vector's you have several bad side effects possible:

  1. You can obtain illegal access to as i assume, memory layout, fay beyound bounds from static array data
  2. static matrix (vector[x][y]) will never work properly with this approach, and case 1. will go 10x badly
  3. You cant shurely know, is GetClassVar will return broken data of memory, or an valid data, because of https://feedback.bistudio.com/T170150 is persistent at moment

Im not sure, but looks like vector static matrices is broken

Details

Severity
Minor
Resolution
Open
Reproducibility
Always
Operating System
Windows 11 x64
Operating System Version
24H2 Pro
Category
General
Steps To Reproduce
class VectorTestClass
{
    vector RandomizeVector() { return Vector(Math.RandomFloat(0, 100), Math.RandomFloat(0, 100), Math.RandomFloat(0, 100)); }

    vector vecarr[2] = { RandomizeVector(), RandomizeVector() };
    vector vecmat[2][2] = { { RandomizeVector(), RandomizeVector() }, { RandomizeVector(), RandomizeVector() } };

    void DebugPrint()
    {
        Print("=== VectorTestClass ===");
        for (int i = 0; i < 2; i++)
        {
            Print("vecarr[" + i + "]: " + vecarr[i]);
        }
        for (i = 0; i < 2; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                // vector vec_ = vecmat[i][j];
                float x = vecmat[i][j][0]; // because vector vec = vecmat[i][j]; doesn't work due to syntax check error (Incompatible parameter)
                float y = vecmat[i][j][1];
                float z = vecmat[i][j][2];
                Print("vecmat[" + i + "][" + j + "]: " + x + " " + y + " " + z);
            }
        }
        Print("=== VectorTestClass ===");
    }
}


[VectorMemLeakTest()]
class VectorMemLeakTest {
    void VectorMemLeakTest()
    {
        Print("VectorMemLeakTest");
        VectorTestClass tc = new VectorTestClass();
        tc.DebugPrint();

        for (int i = 0; i < 10; i++)
        {
            vector vec;
            EnScript.GetClassVar(tc, "vecarr", i, vec);
            Print("vecarr[" + i + "]: " + vec);
        }

        for (i = 0; i < 10; i++)
        {
            vector _vec;
            EnScript.GetClassVar(tc, "vecmat", i, _vec);
            Print ("vecmat[" + i + "]: " + _vec);
        }
    }
}

Example output

=== VectorTestClass ===
vecarr[0]: <2.291940, 47.053432, 76.616714>
vecarr[1]: <8.078249, 68.227173, 29.203159>
vecmat[0][0]: 4.04675 61.1988 10.1321
vecmat[0][1]: 77.1325 59.8834 34.9528
vecmat[1][0]: 7.00624e+22 2.93086e+26 7.02934e+28
vecmat[1][1]: 1.70523e+28 1.69287e+22 2.62215e+20
=== VectorTestClass ===
vecarr[0]: <2.291940, 47.053432, 76.616714>
vecarr[1]: <8.078249, 68.227173, 29.203159>
vecarr[2]: <-0.000000, 0.000000, 4.046754>
vecarr[3]: <61.198761, 10.132144, 77.132477>
vecarr[4]: <59.883415, 34.952847, 70062400323811004121088.000000>
vecarr[5]: <293086426188883562334257152.000000, 70293426239209037370650263552.000000, 17052335504564009951412879360.000000>
vecarr[6]: <293086426188883562334257152.000000, 70293426239209037370650263552.000000, 17052335504564009951412879360.000000>
vecarr[7]: <293086426188883562334257152.000000, 70293426239209037370650263552.000000, 17052335504564009951412879360.000000>
vecarr[8]: <293086426188883562334257152.000000, 70293426239209037370650263552.000000, 17052335504564009951412879360.000000>
vecarr[9]: <293086426188883562334257152.000000, 70293426239209037370650263552.000000, 17052335504564009951412879360.000000>
vecmat[0]: <4.046754, 61.198761, 10.132144>
vecmat[1]: <77.132477, 59.883415, 34.952847>
vecmat[2]: <70062400323811004121088.000000, 293086426188883562334257152.000000, 70293426239209037370650263552.000000>
vecmat[3]: <17052335504564009951412879360.000000, 16928743894809449594880.000000, 262214981060485185536.000000>
vecmat[4]: <17052335504564009951412879360.000000, 16928743894809449594880.000000, 262214981060485185536.000000>
vecmat[5]: <17052335504564009951412879360.000000, 16928743894809449594880.000000, 262214981060485185536.000000>
vecmat[6]: <17052335504564009951412879360.000000, 16928743894809449594880.000000, 262214981060485185536.000000>
vecmat[7]: <17052335504564009951412879360.000000, 16928743894809449594880.000000, 262214981060485185536.000000>
vecmat[8]: <17052335504564009951412879360.000000, 16928743894809449594880.000000, 262214981060485185536.000000>
vecmat[9]: <17052335504564009951412879360.000000, 16928743894809449594880.000000, 262214981060485185536.000000>
Additional Information

While working around this issue, ive found, that there is persists some special values for vector for system data:
for array end Vector(0, 1.79662e+29, 0) OR Vector(0, 1.79663e+29, 0)
for memory bounds there is Vector(0, 0, 1.64307e+24)
for unitialized memory there is Vector(-1e+06, -1e+06, -1e+06)
Im 100% not sure about this info, so just for anybody stuck with simmilar issue, ive made solution (KINDA WORKS FOR ME)

static ref array<vector> ANOMALY_MARKERS = {
    Vector(0, 1.79662e+29, 0),    
    Vector(0, 1.79663e+29, 0),    
    Vector(0, 0, 1.64307e+24),    
    Vector(-1e+06, -1e+06, -1e+06) 
};

bool IsAnomaly(vector value)
{
    // Print("Checking anomaly: " + value.ToString());
    foreach(vector anomaly : ANOMALY_MARKERS)
    {
        if (value == anomaly)
        {
            // Print ("A1nomaly found: " + value.ToString());
            return true;
        }
    }

    if (value[0] > int.MAX || value[1] > int.MAX || value[2] > int.MAX || value[0] < int.MIN || value[1] < int.MIN || value[2] < int.MIN)
    {
        // Print ("2Anomaly found: " + value.ToString());
        return true;
    }

    return false;
}

Event Timeline

Geez changed the task status from New to Assigned.Thu, Dec 12, 12:09 PM