5 files modified
102 ■■■■ changed files
afl-mojodds.c 11 ●●●● patch | view | raw | blame | history
ddsinfo.c 5 ●●●●● patch | view | raw | blame | history
glddstest.c 22 ●●●● patch | view | raw | blame | history
mojodds.c 60 ●●●● patch | view | raw | blame | history
mojodds.h 4 ●●●● patch | view | raw | blame | history
afl-mojodds.c
@@ -13,10 +13,17 @@
// if you don't know what this is you don't need it
void __afl_manual_init(void);
int main(int argc, char *argv[]) {
    if (argc != 2) {
        return 0;
    }
#ifdef __AFL_HAVE_MANUAL_INIT
    __afl_manual_init();
#endif  // __AFL_HAVE_MANUAL_INIT
    const char *filename = argv[1];
@@ -66,7 +73,7 @@
        const void *miptex = NULL;
        unsigned long miptexlen = 0;
        unsigned int mipW = 0, mipH = 0;
        retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
        retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH);
        if (!retval) {
            continue;
        }
@@ -85,7 +92,7 @@
                const void *miptex = NULL;
                unsigned long miptexlen = 0;
                unsigned int mipW = 0, mipH = 0;
                retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                if (!retval) {
                    continue;
                }
ddsinfo.c
@@ -74,7 +74,7 @@
            const void *miptex = NULL;
            unsigned long miptexlen = 0;
            unsigned int mipW = 0, mipH = 0;
            retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
            retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH);
            if (!retval) {
                printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval);
                continue;
@@ -90,13 +90,14 @@
        case MOJODDS_TEXTURE_CUBE:
            printf("cube\n");
            printf("cubemapfacelen: %u\n", cubemapfacelen);
            printf("\n");
            for (unsigned int miplevel = 0; miplevel < miplevels; miplevel++) {
                const void *miptex = NULL;
                unsigned long miptexlen = 0;
                unsigned int mipW = 0, mipH = 0;
                retval = MOJODDS_getCubeFace(MOJODDS_CUBEFACE_POSITIVE_X, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                retval = MOJODDS_getCubeFace(MOJODDS_CUBEFACE_POSITIVE_X, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                if (!retval) {
                    printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval);
                    continue;
glddstest.c
@@ -51,7 +51,10 @@
static int glddstest(const char *filename) {
    printf("%s\n", filename);
    printf("%s\n", filename);
    if (GLEW_GREMEDY_string_marker) {
        glStringMarkerGREMEDY(0, filename);
    }
    FILE *f = fopen(filename, "rb");
    if (!f) {
@@ -89,9 +92,16 @@
            return 3;
        }
        GLint maxTexSize = 0;
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
        if (w > maxTexSize || h > maxTexSize) {
            printf("Texture too large: %ux%u vs %d\n", w, h, maxTexSize);
            return 4;
        }
        bool isCompressed = true;
        GLenum internalFormat = glfmt;
        if (glfmt == GL_BGRA || glfmt == GL_BGR) {
        if (glfmt == GL_BGRA || glfmt == GL_BGR || glfmt == GL_LUMINANCE_ALPHA) {
            isCompressed = false;
            if (glfmt == GL_BGR) {
                internalFormat = GL_RGB8;
@@ -116,7 +126,7 @@
            const void *miptex = NULL;
            unsigned long miptexlen = 0;
            unsigned int mipW = 0, mipH = 0;
            retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
            retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH);
            if (!retval) {
                printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval);
                continue;
@@ -142,7 +152,7 @@
                const void *miptex = NULL;
                unsigned long miptexlen = 0;
                unsigned int mipW = 0, mipH = 0;
                retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                retval = MOJODDS_getMipMapTexture(miplevel, glfmt, tex, w, h, &miptex, &miptexlen, &mipW, &mipH);
                if (!retval) {
                    printf("MOJODDS_getMipMapTexture(%u) error: %d\n", miplevel, retval);
                    continue;
@@ -168,7 +178,7 @@
                    const void *miptex = NULL;
                    unsigned long miptexlen = 0;
                    unsigned int mipW = 0, mipH = 0;
                    retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                    retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                    if (!retval) {
                        printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval);
                        continue;
@@ -196,7 +206,7 @@
                        const void *miptex = NULL;
                        unsigned long miptexlen = 0;
                        unsigned int mipW = 0, mipH = 0;
                        retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, texlen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                        retval = MOJODDS_getCubeFace(cubeFace, miplevel, glfmt, tex, cubemapfacelen, w, h, &miptex, &miptexlen, &mipW, &mipH);
                        if (!retval) {
                            printf("MOJODDS_getCubeFace(%u, %u) error: %d\n", cubeFace, miplevel, retval);
                            continue;
mojodds.c
@@ -104,6 +104,25 @@
} MOJODDS_Header;
//http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
static const uint32_t MultiplyDeBruijnBitPosition[32] =
{
  0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
  8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
static uint32_t uintLog2(uint32_t v) {
    v |= v >> 1; // first round down to one less than a power of 2
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
}
static uint32 readui32(const uint8 **_ptr, size_t *_len)
{
    uint32 retval = 0;
@@ -194,9 +213,15 @@
    *_miplevels = (header->dwCaps & DDSCAPS_MIPMAP) ? header->dwMipMapCount : 1;
    if (*_miplevels > 32)
    unsigned int calculatedMipLevels = uintLog2(MAX(width, height)) + 1;
    if (*_miplevels == 0)
    {
        // too many mip levels, width and height would be larger than 32-bit int
        // invalid, calculate it ourselves from size
        *_miplevels = calculatedMipLevels;
    }
    else if (*_miplevels > calculatedMipLevels)
    {
        // too many mip levels, several would be 1x1
        // file is corrupted
        return 0;
    }
@@ -326,9 +351,19 @@
        *_cubemapfacelen = 0;
        for (i = 0; i < (int)*_miplevels; i++)
        {
            *_cubemapfacelen += ((MAX( wd, blockDim ) / blockDim) * (MAX( ht, blockDim ) / blockDim)) * blockSize;
            uint32_t mipLen = MAX((wd + blockDim - 1) / blockDim, 1) * MAX((ht + blockDim - 1) / blockDim, 1) * blockSize;
            if (UINT32_MAX - mipLen < *_cubemapfacelen) {
                // data size would overflow 32-bit uint, invalid file
                return 0;
            }
            *_cubemapfacelen += mipLen;
            wd >>= 1;
            ht >>= 1;
        }
        // 6 because cube faces
        if (*len < (*_cubemapfacelen) * 6) {
            return 0;
        }
    }
    else if (*_textureType == MOJODDS_TEXTURE_2D)
@@ -337,10 +372,15 @@
        // TODO: also do this for other texture types
        uint32 wd = header->dwWidth;
        uint32 ht = header->dwHeight;
        uint32 dataLen = 0;
        uint32_t dataLen = 0;
        for (i = 0; i < (int)*_miplevels; i++)
        {
            dataLen += MAX((wd + blockDim - 1) / blockDim, 1) * MAX((ht + blockDim - 1) / blockDim, 1) * blockSize;
            uint32_t mipLen = MAX((wd + blockDim - 1) / blockDim, 1) * MAX((ht + blockDim - 1) / blockDim, 1) * blockSize;
            if (UINT32_MAX - mipLen < dataLen) {
                // data size would overflow 32-bit uint, invalid file
                return 0;
            }
            dataLen += mipLen;
            wd >>= 1;
            ht >>= 1;
        }
@@ -398,7 +438,7 @@
} // MOJODDS_getTexture
int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt,
                             const void*_basetex, const unsigned long _basetexlen,
                             const void*_basetex,
                             unsigned int w, unsigned h,
                             const void **_tex, unsigned long *_texlen,
                             unsigned int *_texw, unsigned int *_texh)
@@ -443,9 +483,9 @@
    assert(blockSize != 0);
    newtex = _basetex;
    newtexlen = _basetexlen;
    neww = w;
    newh = h;
    newtexlen = ((neww + blockDim - 1) / blockDim) * ((newh + blockDim - 1) / blockDim) * blockSize;
    // Calculate size of miplevel
    for (i=0; i < miplevel; ++i)
@@ -472,17 +512,17 @@
int MOJODDS_getCubeFace(MOJODDS_cubeFace cubeFace, unsigned int miplevel,
                        unsigned int glfmt, const void *_basetex,
                        unsigned long _basetexlen, unsigned int w, unsigned h,
                        unsigned long _cubemapfacelen, unsigned int w, unsigned h,
                        const void **_tex, unsigned long *_texlen,
                        unsigned int *_texw, unsigned int *_texh)
{
    // pick correct face
    const char *faceBaseTex = (const char *) _basetex;
    faceBaseTex = faceBaseTex + cubeFace * _basetexlen;
    faceBaseTex = faceBaseTex + cubeFace * _cubemapfacelen;
    // call MOJODDS_getMipMapTexture to get offset in that face
    return MOJODDS_getMipMapTexture(miplevel, glfmt, faceBaseTex, _basetexlen, w, h, _tex, _texlen, _texw, _texh);
    return MOJODDS_getMipMapTexture(miplevel, glfmt, faceBaseTex, w, h, _tex, _texlen, _texw, _texh);
}
mojodds.h
@@ -35,14 +35,14 @@
                       unsigned int *_cubemapfacelen,
                       MOJODDS_textureType *_textureType);
int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt,
                             const void*_basetex, const unsigned long _basetexlen,
                             const void*_basetex,
                             unsigned int w, unsigned h,
                             const void **_tex, unsigned long *_texlen,
                             unsigned int *_texw, unsigned int *_texh);
int MOJODDS_getCubeFace(MOJODDS_cubeFace cubeFace, unsigned int miplevel,
                        unsigned int glfmt, const void*_basetex,
                        unsigned long _basetexlen, unsigned int w, unsigned h,
                        unsigned long _cubemapfacelen, unsigned int w, unsigned h,
                        const void **_tex, unsigned long *_texlen,
                        unsigned int *_texw, unsigned int *_texh);