ladislav-zezula / StormLib

Official GitHub repository of the StormLib library created by Ladislav Zezula (author)
http://www.zezula.net/mpq.html
MIT License
560 stars 213 forks source link

Reading (listfile) with SFileReadFile() has different outputs every run on Linux #162

Closed SimonMossmyr closed 4 years ago

SimonMossmyr commented 4 years ago

Sample code:

#include <StormLib.h>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{    
    char* archive_file_name = argv[1];

    /** Open w3x as MPQ archive */
    HANDLE hMpq = NULL;
    !SFileOpenArchive(archive_file_name, 0, MPQ_OPEN_READ_ONLY, &hMpq);

    /** Open archive listfile */
    HANDLE listfile_handle = NULL;
    !SFileOpenFileEx(hMpq, "(listfile)", SFILE_OPEN_FROM_MPQ, &listfile_handle);

    /** Find size of listfile */
    DWORD size_of_listfile_high = -1;
    DWORD size_of_listfile_low = 0;
    size_of_listfile_low = SFileGetFileSize(listfile_handle, &size_of_listfile_high);

    /** Read contents of listfile */
    char listfile_buffer[size_of_listfile_low];
    DWORD number_of_chars_actually_read = 0;
    !SFileReadFile(listfile_handle, &listfile_buffer, size_of_listfile_low, &number_of_chars_actually_read, NULL);

    /** Print listfile */
    cout << listfile_buffer << endl;

    return 0;
}

Compile:

$ g++ -o main main.cpp -lstorm -lz -lbz2

Output (using (8)GoldRush.w3x):

$ ./main maps/GoldRush.w3x 
war3map.w3e
war3map.w3i
war3map.wtg
war3map.wct
war3map.wts
war3map.j
war3map.shd
war3mapMap.blp
war3map.mmp
war3map.wpm
war3map.doo
war3mapUnits.doo
war3map.w3r
war3map.w3c
@V

$ ./main maps/GoldRush.w3x 
war3map.w3e
war3map.w3i
war3map.wtg
war3map.wct
war3map.wts
war3map.j
war3map.shd
war3mapMap.blp
war3map.mmp
war3map.wpm
war3map.doo
war3mapUnits.doo
war3map.w3r
war3map.w3c
FV

The last line, i.e. @V and FV, is different on every run. And shouldn't be there.

Using StormLib-9.22 on Ubuntu 19.04.

DarkAyron commented 4 years ago

You are printing the garbage behind the buffer. You need to make the buffer one byte larger and add a zero-terminator at the end of the read contents before using cout.

listfile_buffer[number_of_chars_actually_read] = 0;