zturtleman / mm3d

Maverick Model 3D is a 3D model editor and animator for games.
https://clover.moe/mm3d
GNU General Public License v2.0
110 stars 22 forks source link

Unaligned read in datasource.cc #151

Open m-7761 opened 3 years ago

m-7761 commented 3 years ago

I noticed the read family of methods is dereferencing unaligned pointers (the MM3D format is completely unaligned unfortunately) in which case I don't think it will work on architectures like ARM that require alignment.

I was just removing endianconfig.h to put in a simpler system in its place, since none of the loaders are using "swapEndianness" and the setup was sloppy. Below is the new code I wrote in case useful.

template<class T>
inline bool DataSource::_read(T &val)
{
    if(!requireBytes(sizeof(val))) return false;

    //This is an unaligned read, which doesn't 
    //work for ARM systems.
    //m_endfunc16(*(uint16_t*)m_buf);
    memcpy(&val,m_buf,sizeof(T));

    if(m_swap) swapEndianness(val);

    advanceBytes(sizeof(val)); return true;
}
bool DataSource::read(int8_t &val){ return _read(val); }
bool DataSource::read(uint8_t &val){ return _read(val); }
bool DataSource::read(int16_t &val){ return _read(val); }
bool DataSource::read(uint16_t &val){ return _read(val); }
bool DataSource::read(int32_t &val){ return _read(val); }
bool DataSource::read(uint32_t &val){ return _read(val); }
bool DataSource::read(float &val){ return _read(val); }
template<class T>
inline bool DataDest::_write(T &val)
{
    if(!canWrite(sizeof(T))) return false;

    if(m_swap) swapEndianness(val);

    return internalWrite((const uint8_t*)&val,sizeof(T));
}
bool DataDest::write(int8_t val){ return _write(val); }
bool DataDest::write(uint8_t val){ return _write(val); }
bool DataDest::write(int16_t val){ return _write(val); }
bool DataDest::write(uint16_t val){ return _write(val); }
bool DataDest::write(int32_t val){ return _write(val); }
bool DataDest::write(uint32_t val){ return _write(val); }
bool DataDest::write(float val){ return _write(val); }