#19 Extension Verification

open
nobody
None
4
2012-09-15
2007-03-08
No

this bug applies to all versions. Extensions are verified in their init functions, but the verification mechanism is faulty. Here is a pseudocode example:

static GLboolean _glewInit_GL_FOO_EXT(GLEW_CONTEXT_ARG_DEF_INIT)
{
GLboolean r = GL_FALSE;

r = ((func1 = (FUNCT)glewGetProcAddress((const GLubyte)"func1")) == NULL) || r;
r = ((func2 = (FUNCT)glewGetProcAddress((const GLubyte
)"func2")) == NULL) || r;
r = ((func3 = (FUNCT)glewGetProcAddress((const GLubyte*)"func3")) == NULL) || r;

return r;
}

Say that func1 and func3 are successfully found, but func2 isn't. This would still return TRUE because of the || operations. The user could then mistakenly use func2 and crash. This can easily be solved initializing the result to TRUE and performing an &= like so:

static GLboolean _glewInit_GL_FOO_EXT(GLEW_CONTEXT_ARG_DEF_INIT)
{
GLboolean r = GL_TRUE;

r &= ((func1 = (FUNCT)glewGetProcAddress((const GLubyte)"func1")) == NULL);
r &= ((func2 = (FUNCT)glewGetProcAddress((const GLubyte
)"func2")) == NULL);
r &= ((func3 = (FUNCT)glewGetProcAddress((const GLubyte*)"func3")) == NULL);

return r;
}

Now if any of them are FALSE, the entire thing will be FALSE.

You could also just change the initial GL_FALSE to GL_TRUE and change the || into &&.

Discussion

  • Milan Ikits

    Milan Ikits - 2007-03-18

    Logged In: YES
    user_id=653379
    Originator: NO

    Jason,

    The return value of any glewInit... function indicates whether the function failed or not. The corresponding variable is assigned !glewInit..., i.e. when the function succeeds (no GL function is assigned NULL), the resulting variable becomes GL_TRUE. In other words, the GLEW_... variable is assigned !(NULL || NULL || NULL ...), which is equivalent to !NULL && !NULL && !NULL (basically what you suggested -- but replacing == with !=).

    There is some disagreement between the unix and windows worlds about whether a function should return true or false on success. GLEW follows the unix convention (0 success, !0 failure).

    • Milan
     
  • Jason Tipton

    Jason Tipton - 2007-03-20

    Logged In: YES
    user_id=1477482
    Originator: YES

    I missed the ! when the function is used. I see your point. I thought GL_TRUE indicated success instead of failure. I would consider returning an int instead of a bool, since a boolean has certain logical ramifications. Consider this code:

    if(init()) // bool
    {
    // Function Initialized
    }

    if(init() == 0) // int
    {
    // Function Initialized
    }

    It doesn't change the function logic, but does change the implicit meaning of the return type. I realize that ints and bools convert to each other, but they do signify things to the user.

    Thanks,
    Jason

     
  • Nigel Stewart

    Nigel Stewart - 2008-10-21

    Could "r" for return be renamed to "f" for fail?

    That might help clarify the logic.

     
  • Nigel Stewart

    Nigel Stewart - 2009-12-01

    I think r -> ret is more consistent within the GLEW codebase than something such as "f", "fail", "err", "error".

    Proposed patch as follows:

    Index: auto/Makefile

    --- auto/Makefile (revision 564)
    +++ auto/Makefile (working copy)
    @@ -214,7 +214,7 @@
    perl -e "s/GLEW_VERSION_MINOR_STRING/$(GLEW_MINOR)/g" -pi $@
    perl -e "s/GLEW_VERSION_MICRO_STRING/$(GLEW_MICRO)/g" -pi $@
    perl -e "s/GLEW_ARB_vertex_shader = !_glewInit_GL_ARB_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT);/{ GLEW_ARB_vertex_shader = !_glewInit_GL_ARB_vertex_shader(GLEW_CONTEXT_ARG_VAR_INIT); _glewInit_GL_ARB_vertex_program(GLEW_CONTEXT_ARG_VAR_INIT); }/g" -pi $@
    - perl -e "s/((glColorSubTable = /((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte)\"glBlendEquation\")) == NULL) || r;\n r = ((glColorSubTable = /g" -pi $@
    + perl -e "s/((glColorSubTable = /((glBlendEquation = (PFNGLBLENDEQUATIONPROC)glewGetProcAddress((const GLubyte
    )\"glBlendEquation\")) == NULL) || ret;\n ret = ((glColorSubTable = /g" -pi $@
    $(BIN)/fix_OML_sync_control.sh $@
    rm -f $@.bak

    Index: auto/bin/make_init.pl

    --- auto/bin/make_init.pl (revision 564)
    +++ auto/bin/make_init.pl (working copy)
    @@ -18,7 +18,7 @@
    sub make_pfn_def_init($%)
    {
    #my $name = prefixname($[0]);
    - return " r = ((" . $
    [0] . " = (PFN" . (uc $[0]) . "PROC)glewGetProcAddress((const GLubyte)\"" . $[0] . "\")) == NULL) || r;";
    + return " ret = ((" . $
    [0] . " = (PFN" . (uc $_[0]) . "PROC)glewGetProcAddress((const GLubyte
    )\"" . $
    [0] . "\")) == NULL) || ret;";
    }

    #-------------------------------------------------------------------------------
    @@ -45,9 +45,9 @@
    if (keys %$functions)
    {
    print "static GLboolean glewInit$extname (" . $type .
    - "EW_CONTEXT_ARG_DEF_INIT)\n{\n GLboolean r = GL_FALSE;\n";
    + "EW_CONTEXT_ARG_DEF_INIT)\n{\n GLboolean ret = GL_FALSE;\n";
    output_decls($functions, \&make_pfn_def_init);
    - print "\n return r;\n}\n\n";
    + print "\n return ret;\n}\n\n";
    }
    #print "\nGLboolean " . prefix_varname($extvar) . " = GL_FALSE;\n\n";
    print "#endif / $extname /\n\n";

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks