/** * Adds the limit parameter to the criteria * * @param int $limit * @param int $offset * @return Phalcon\Mvc\Model\CriteriaInterface */ PHP_METHOD(Phalcon_Mvc_Model_Criteria, limit){ zval *limit, *offset = NULL, *limit_clause; PHALCON_MM_GROW(); phalcon_fetch_params(1, 1, 1, &limit, &offset); if (!offset) { offset = PHALCON_GLOBAL(z_null); } if (!phalcon_is_numeric(limit)) { PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_model_exception_ce, "Row limit parameter must be integer"); return; } if (Z_TYPE_P(offset) == IS_NULL) { phalcon_update_property_array_string(this_ptr, SL("_params"), ISS(limit), limit TSRMLS_CC); } else { PHALCON_INIT_VAR(limit_clause); array_init_size(limit_clause, 2); phalcon_array_update_string(&limit_clause, ISL(number), limit, PH_COPY); phalcon_array_update_string(&limit_clause, ISL(offset), offset, PH_COPY); phalcon_update_property_array_string(this_ptr, SL("_params"), ISS(limit), limit_clause TSRMLS_CC); } RETURN_THIS(); }
bool ParseDictionaryFile(const std::string &Text, std::vector<Unit> *Units) { if (Text.empty()) { Printf("ParseDictionaryFile: file does not exist or is empty\n"); return false; } std::istringstream ISS(Text); Units->clear(); Unit U; int LineNo = 0; std::string S; while (std::getline(ISS, S, '\n')) { LineNo++; size_t Pos = 0; while (Pos < S.size() && isspace(S[Pos])) Pos++; // Skip spaces. if (Pos == S.size()) continue; // Empty line. if (S[Pos] == '#') continue; // Comment line. if (ParseOneDictionaryEntry(S, &U)) { Units->push_back(U); } else { Printf("ParseDictionaryFile: error in line %d\n\t\t%s\n", LineNo, S.c_str()); return false; } } return true; }
/** * Adds the order-by parameter to the criteria * * @param string $orderColumns * @return Phalcon\Mvc\Model\CriteriaInterface */ PHP_METHOD(Phalcon_Mvc_Model_Criteria, orderBy){ zval *order_columns; phalcon_fetch_params(0, 1, 0, &order_columns); if (Z_TYPE_P(order_columns) != IS_STRING) { PHALCON_THROW_EXCEPTION_STRW(phalcon_mvc_model_exception_ce, "Order columns must be string"); return; } phalcon_update_property_array_string(this_ptr, SL("_params"), ISS(order), order_columns TSRMLS_CC); RETURN_THISW(); }
// function that takes a comma seperated line and converts to vector std::vector<std::string> File::lineToVector(std::string t_line) { std::vector<std::string> tempStringVector; std::istringstream ISS(t_line); for (std::string token; std::getline(ISS, token, ',');) { // if there is a space at the front if (token[0] == ' ') { // remove it (remove head of sequence) token.erase(0, 1); } // display token //std::cout << token << std::endl; // add it to vector tempStringVector.push_back(token); } return tempStringVector; // vectors default passed by value not ref }
void CSaveGame :: ParseSaveGame( ) { m_MapPath.clear( ); m_Slots.clear( ); m_MagicNumber.clear( ); istringstream ISS( m_Decompressed ); // savegame format figured out by Varlock: // string -> map path // 0 (string?) -> ??? (no idea what this is) // string -> original game name // 0 (string?) -> ??? (maybe original game password) // string -> stat string // 4 bytes -> ??? (seems to be # of slots) // 4 bytes -> ??? (seems to be 0x01 0x28 0x49 0x00 on both of the savegames examined) // 2 bytes -> ??? (no idea what this is) // slot structure // 4 bytes -> magic number string GarbageString; unsigned char NumSlots; uint32_t MagicNumber; getline( ISS, m_MapPath, '\0' ); // map path getline( ISS, GarbageString, '\0' ); // ??? getline( ISS, GarbageString, '\0' ); // original game name getline( ISS, GarbageString, '\0' ); // ??? getline( ISS, GarbageString, '\0' ); // stat string ISS.seekg( 4, ios :: cur ); // ??? ISS.seekg( 4, ios :: cur ); // ??? ISS.seekg( 2, ios :: cur ); // ??? ISS.read( (char *)&NumSlots, 1 ); // number of slots if( NumSlots > 12 ) { CONSOLE_Print( "[SAVEGAME] too many slots in decompressed data" ); m_Valid = false; return; } CONSOLE_Print( "[SAVEGAME] found " + UTIL_ToString( NumSlots ) + " slots" ); for( unsigned char i = 0; i < NumSlots; i++ ) { unsigned char SlotData[9]; ISS.read( (char *)SlotData, 9 ); // slot data m_Slots.push_back( CGameSlot( SlotData[0], SlotData[1], SlotData[2], SlotData[3], SlotData[4], SlotData[5], SlotData[6], SlotData[7], SlotData[8] ) ); } ISS.seekg( 4, ios :: cur ); // GetTicks ISS.seekg( 1, ios :: cur ); // GameType ISS.seekg( 1, ios :: cur ); // number of player slots (non observer) ISS.read( (char *)&MagicNumber, 4 ); // magic number if( ISS.fail( ) ) { CONSOLE_Print( "[SAVEGAME] failed to parse decompressed data" ); m_Valid = false; return; } m_MagicNumber = UTIL_CreateByteArray( MagicNumber, false ); CONSOLE_Print( "[SAVEGAME] found map path [" + m_MapPath + "]" ); CONSOLE_Print( "[SAVEGAME] found magic number [" + UTIL_ToString( m_MagicNumber[0] ) + " " + UTIL_ToString( m_MagicNumber[1] ) + " " + UTIL_ToString( m_MagicNumber[2] ) + " " + UTIL_ToString( m_MagicNumber[3] ) + "]" ); }
void CMap :: Load( CConfig *CFG, string nCFGFile ) { m_Valid = true; m_CFGFile = nCFGFile; // load the map data m_MapLocalPath = CFG->GetString( "map_localpath", string( ) ); m_MapData.clear( ); if( !m_MapLocalPath.empty( ) ) m_MapData = UTIL_FileRead( m_GHost->m_MapPath + m_MapLocalPath ); // load the map MPQ string MapMPQFileName = m_GHost->m_MapPath + m_MapLocalPath; HANDLE MapMPQ; bool MapMPQReady = false; if( SFileOpenArchive( MapMPQFileName.c_str( ), 0, MPQ_OPEN_FORCE_MPQ_V1, &MapMPQ ) ) { CONSOLE_Print( "[MAP] loading MPQ file [" + MapMPQFileName + "]" ); MapMPQReady = true; } else CONSOLE_Print( "[MAP] warning - unable to load MPQ file [" + MapMPQFileName + "]" ); // try to calculate map_size, map_info, map_crc, map_sha1 BYTEARRAY MapSize; BYTEARRAY MapInfo; BYTEARRAY MapCRC; BYTEARRAY MapSHA1; if( !m_MapData.empty( ) ) { m_GHost->m_SHA->Reset( ); // calculate map_size MapSize = UTIL_CreateByteArray( (uint32_t)m_MapData.size( ), false ); CONSOLE_Print( "[MAP] calculated map_size = " + UTIL_ByteArrayToDecString( MapSize ) ); // calculate map_info (this is actually the CRC) MapInfo = UTIL_CreateByteArray( (uint32_t)m_GHost->m_CRC->FullCRC( (unsigned char *)m_MapData.c_str( ), m_MapData.size( ) ), false ); CONSOLE_Print( "[MAP] calculated map_info = " + UTIL_ByteArrayToDecString( MapInfo ) ); // calculate map_crc (this is not the CRC) and map_sha1 // a big thank you to Strilanc for figuring the map_crc algorithm out string CommonJ = UTIL_FileRead( m_GHost->m_MapCFGPath + "common.j" ); if( CommonJ.empty( ) ) CONSOLE_Print( "[MAP] unable to calculate map_crc/sha1 - unable to read file [" + m_GHost->m_MapCFGPath + "common.j]" ); else { string BlizzardJ = UTIL_FileRead( m_GHost->m_MapCFGPath + "blizzard.j" ); if( BlizzardJ.empty( ) ) CONSOLE_Print( "[MAP] unable to calculate map_crc/sha1 - unable to read file [" + m_GHost->m_MapCFGPath + "blizzard.j]" ); else { uint32_t Val = 0; // update: it's possible for maps to include their own copies of common.j and/or blizzard.j // this code now overrides the default copies if required bool OverrodeCommonJ = false; bool OverrodeBlizzardJ = false; if( MapMPQReady ) { HANDLE SubFile; // override common.j if( SFileOpenFileEx( MapMPQ, "Scripts\\common.j", 0, &SubFile ) ) { uint32_t FileLength = SFileGetFileSize( SubFile, NULL ); if( FileLength > 0 && FileLength != 0xFFFFFFFF ) { char *SubFileData = new char[FileLength]; DWORD BytesRead = 0; if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) ) { CONSOLE_Print( "[MAP] overriding default common.j with map copy while calculating map_crc/sha1" ); OverrodeCommonJ = true; Val = Val ^ XORRotateLeft( (unsigned char *)SubFileData, BytesRead ); m_GHost->m_SHA->Update( (unsigned char *)SubFileData, BytesRead ); } delete [] SubFileData; } SFileCloseFile( SubFile ); } } if( !OverrodeCommonJ ) { Val = Val ^ XORRotateLeft( (unsigned char *)CommonJ.c_str( ), CommonJ.size( ) ); m_GHost->m_SHA->Update( (unsigned char *)CommonJ.c_str( ), CommonJ.size( ) ); } if( MapMPQReady ) { HANDLE SubFile; // override blizzard.j if( SFileOpenFileEx( MapMPQ, "Scripts\\blizzard.j", 0, &SubFile ) ) { uint32_t FileLength = SFileGetFileSize( SubFile, NULL ); if( FileLength > 0 && FileLength != 0xFFFFFFFF ) { char *SubFileData = new char[FileLength]; DWORD BytesRead = 0; if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) ) { CONSOLE_Print( "[MAP] overriding default blizzard.j with map copy while calculating map_crc/sha1" ); OverrodeBlizzardJ = true; Val = Val ^ XORRotateLeft( (unsigned char *)SubFileData, BytesRead ); m_GHost->m_SHA->Update( (unsigned char *)SubFileData, BytesRead ); } delete [] SubFileData; } SFileCloseFile( SubFile ); } } if( !OverrodeBlizzardJ ) { Val = Val ^ XORRotateLeft( (unsigned char *)BlizzardJ.c_str( ), BlizzardJ.size( ) ); m_GHost->m_SHA->Update( (unsigned char *)BlizzardJ.c_str( ), BlizzardJ.size( ) ); } Val = ROTL( Val, 3 ); Val = ROTL( Val ^ 0x03F1379E, 3 ); m_GHost->m_SHA->Update( (unsigned char *)"\x9E\x37\xF1\x03", 4 ); if( MapMPQReady ) { vector<string> FileList; FileList.push_back( "war3map.j" ); FileList.push_back( "scripts\\war3map.j" ); FileList.push_back( "war3map.w3e" ); FileList.push_back( "war3map.wpm" ); FileList.push_back( "war3map.doo" ); FileList.push_back( "war3map.w3u" ); FileList.push_back( "war3map.w3b" ); FileList.push_back( "war3map.w3d" ); FileList.push_back( "war3map.w3a" ); FileList.push_back( "war3map.w3q" ); bool FoundScript = false; for( vector<string> :: iterator i = FileList.begin( ); i != FileList.end( ); i++ ) { // don't use scripts\war3map.j if we've already used war3map.j (yes, some maps have both but only war3map.j is used) if( FoundScript && *i == "scripts\\war3map.j" ) continue; HANDLE SubFile; if( SFileOpenFileEx( MapMPQ, (*i).c_str( ), 0, &SubFile ) ) { uint32_t FileLength = SFileGetFileSize( SubFile, NULL ); if( FileLength > 0 && FileLength != 0xFFFFFFFF ) { char *SubFileData = new char[FileLength]; DWORD BytesRead = 0; if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) ) { if( *i == "war3map.j" || *i == "scripts\\war3map.j" ) FoundScript = true; Val = ROTL( Val ^ XORRotateLeft( (unsigned char *)SubFileData, BytesRead ), 3 ); m_GHost->m_SHA->Update( (unsigned char *)SubFileData, BytesRead ); // DEBUG_Print( "*** found: " + *i ); } delete [] SubFileData; } SFileCloseFile( SubFile ); } else { // DEBUG_Print( "*** not found: " + *i ); } } if( !FoundScript ) CONSOLE_Print( "[MAP] couldn't find war3map.j or scripts\\war3map.j in MPQ file, calculated map_crc/sha1 is probably wrong" ); MapCRC = UTIL_CreateByteArray( Val, false ); CONSOLE_Print( "[MAP] calculated map_crc = " + UTIL_ByteArrayToDecString( MapCRC ) ); m_GHost->m_SHA->Final( ); unsigned char SHA1[20]; memset( SHA1, 0, sizeof( unsigned char ) * 20 ); m_GHost->m_SHA->GetHash( SHA1 ); MapSHA1 = UTIL_CreateByteArray( SHA1, 20 ); CONSOLE_Print( "[MAP] calculated map_sha1 = " + UTIL_ByteArrayToDecString( MapSHA1 ) ); } else CONSOLE_Print( "[MAP] unable to calculate map_crc/sha1 - map MPQ file not loaded" ); } } } else CONSOLE_Print( "[MAP] no map data available, using config file for map_size, map_info, map_crc, map_sha1" ); // try to calculate map_width, map_height, map_slot<x>, map_numplayers, map_numteams uint32_t MapOptions = 0; BYTEARRAY MapWidth; BYTEARRAY MapHeight; uint32_t MapNumPlayers = 0; uint32_t MapNumTeams = 0; vector<CGameSlot> Slots; if( !m_MapData.empty( ) ) { if( MapMPQReady ) { HANDLE SubFile; if( SFileOpenFileEx( MapMPQ, "war3map.w3i", 0, &SubFile ) ) { uint32_t FileLength = SFileGetFileSize( SubFile, NULL ); if( FileLength > 0 && FileLength != 0xFFFFFFFF ) { char *SubFileData = new char[FileLength]; DWORD BytesRead = 0; if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) ) { istringstream ISS( string( SubFileData, BytesRead ) ); // war3map.w3i format found at http://www.wc3campaigns.net/tools/specs/index.html by Zepir/PitzerMike string GarbageString; uint32_t FileFormat; uint32_t RawMapWidth; uint32_t RawMapHeight; uint32_t RawMapFlags; uint32_t RawMapNumPlayers; uint32_t RawMapNumTeams; ISS.read( (char *)&FileFormat, 4 ); // file format (18 = ROC, 25 = TFT) if( FileFormat == 18 || FileFormat == 25 ) { ISS.seekg( 4, ios :: cur ); // number of saves ISS.seekg( 4, ios :: cur ); // editor version getline( ISS, GarbageString, '\0' ); // map name getline( ISS, GarbageString, '\0' ); // map author getline( ISS, GarbageString, '\0' ); // map description getline( ISS, GarbageString, '\0' ); // players recommended ISS.seekg( 32, ios :: cur ); // camera bounds ISS.seekg( 16, ios :: cur ); // camera bounds complements ISS.read( (char *)&RawMapWidth, 4 ); // map width ISS.read( (char *)&RawMapHeight, 4 ); // map height ISS.read( (char *)&RawMapFlags, 4 ); // flags ISS.seekg( 1, ios :: cur ); // map main ground type if( FileFormat == 18 ) ISS.seekg( 4, ios :: cur ); // campaign background number else if( FileFormat == 25 ) { ISS.seekg( 4, ios :: cur ); // loading screen background number getline( ISS, GarbageString, '\0' ); // path of custom loading screen model } getline( ISS, GarbageString, '\0' ); // map loading screen text getline( ISS, GarbageString, '\0' ); // map loading screen title getline( ISS, GarbageString, '\0' ); // map loading screen subtitle if( FileFormat == 18 ) ISS.seekg( 4, ios :: cur ); // map loading screen number else if( FileFormat == 25 ) { ISS.seekg( 4, ios :: cur ); // used game data set getline( ISS, GarbageString, '\0' ); // prologue screen path } getline( ISS, GarbageString, '\0' ); // prologue screen text getline( ISS, GarbageString, '\0' ); // prologue screen title getline( ISS, GarbageString, '\0' ); // prologue screen subtitle if( FileFormat == 25 ) { ISS.seekg( 4, ios :: cur ); // uses terrain fog ISS.seekg( 4, ios :: cur ); // fog start z height ISS.seekg( 4, ios :: cur ); // fog end z height ISS.seekg( 4, ios :: cur ); // fog density ISS.seekg( 1, ios :: cur ); // fog red value ISS.seekg( 1, ios :: cur ); // fog green value ISS.seekg( 1, ios :: cur ); // fog blue value ISS.seekg( 1, ios :: cur ); // fog alpha value ISS.seekg( 4, ios :: cur ); // global weather id getline( ISS, GarbageString, '\0' ); // custom sound environment ISS.seekg( 1, ios :: cur ); // tileset id of the used custom light environment ISS.seekg( 1, ios :: cur ); // custom water tinting red value ISS.seekg( 1, ios :: cur ); // custom water tinting green value ISS.seekg( 1, ios :: cur ); // custom water tinting blue value ISS.seekg( 1, ios :: cur ); // custom water tinting alpha value } ISS.read( (char *)&RawMapNumPlayers, 4 ); // number of players uint32_t ClosedSlots = 0; for( uint32_t i = 0; i < RawMapNumPlayers; i++ ) { CGameSlot Slot( 0, 255, SLOTSTATUS_OPEN, 0, 0, 1, SLOTRACE_RANDOM ); uint32_t Colour; uint32_t Status; uint32_t Race; ISS.read( (char *)&Colour, 4 ); // colour Slot.SetColour( Colour ); ISS.read( (char *)&Status, 4 ); // status if( Status == 1 ) Slot.SetSlotStatus( SLOTSTATUS_OPEN ); else if( Status == 2 ) { Slot.SetSlotStatus( SLOTSTATUS_OCCUPIED ); Slot.SetComputer( 1 ); Slot.SetComputerType( SLOTCOMP_NORMAL ); } else { Slot.SetSlotStatus( SLOTSTATUS_CLOSED ); ClosedSlots++; } ISS.read( (char *)&Race, 4 ); // race if( Race == 1 ) Slot.SetRace( SLOTRACE_HUMAN ); else if( Race == 2 ) Slot.SetRace( SLOTRACE_ORC ); else if( Race == 3 ) Slot.SetRace( SLOTRACE_UNDEAD ); else if( Race == 4 ) Slot.SetRace( SLOTRACE_NIGHTELF ); else Slot.SetRace( SLOTRACE_RANDOM ); ISS.seekg( 4, ios :: cur ); // fixed start position getline( ISS, GarbageString, '\0' ); // player name ISS.seekg( 4, ios :: cur ); // start position x ISS.seekg( 4, ios :: cur ); // start position y ISS.seekg( 4, ios :: cur ); // ally low priorities ISS.seekg( 4, ios :: cur ); // ally high priorities if( Slot.GetSlotStatus( ) != SLOTSTATUS_CLOSED ) Slots.push_back( Slot ); } ISS.read( (char *)&RawMapNumTeams, 4 ); // number of teams for( uint32_t i = 0; i < RawMapNumTeams; i++ ) { uint32_t Flags; uint32_t PlayerMask; ISS.read( (char *)&Flags, 4 ); // flags ISS.read( (char *)&PlayerMask, 4 ); // player mask for( unsigned char j = 0; j < 12; j++ ) { if( PlayerMask & 1 ) { for( vector<CGameSlot> :: iterator k = Slots.begin( ); k != Slots.end( ); k++ ) { if( (*k).GetColour( ) == j ) (*k).SetTeam( i ); } } PlayerMask >>= 1; } getline( ISS, GarbageString, '\0' ); // team name } // the bot only cares about the following options: melee, fixed player settings, custom forces // let's not confuse the user by displaying erroneous map options so zero them out now MapOptions = RawMapFlags & ( MAPOPT_MELEE | MAPOPT_FIXEDPLAYERSETTINGS | MAPOPT_CUSTOMFORCES ); CONSOLE_Print( "[MAP] calculated map_options = " + UTIL_ToString( MapOptions ) ); MapWidth = UTIL_CreateByteArray( (uint16_t)RawMapWidth, false ); CONSOLE_Print( "[MAP] calculated map_width = " + UTIL_ByteArrayToDecString( MapWidth ) ); MapHeight = UTIL_CreateByteArray( (uint16_t)RawMapHeight, false ); CONSOLE_Print( "[MAP] calculated map_height = " + UTIL_ByteArrayToDecString( MapHeight ) ); MapNumPlayers = RawMapNumPlayers - ClosedSlots; CONSOLE_Print( "[MAP] calculated map_numplayers = " + UTIL_ToString( MapNumPlayers ) ); MapNumTeams = RawMapNumTeams; CONSOLE_Print( "[MAP] calculated map_numteams = " + UTIL_ToString( MapNumTeams ) ); uint32_t SlotNum = 1; for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); i++ ) { CONSOLE_Print( "[MAP] calculated map_slot" + UTIL_ToString( SlotNum ) + " = " + UTIL_ByteArrayToDecString( (*i).GetByteArray( ) ) ); SlotNum++; } if( MapOptions & MAPOPT_MELEE ) { CONSOLE_Print( "[MAP] found melee map, initializing slots" ); // give each slot a different team and set the race to random unsigned char Team = 0; for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); i++ ) { (*i).SetTeam( Team++ ); (*i).SetRace( SLOTRACE_RANDOM ); } } if( !( MapOptions & MAPOPT_FIXEDPLAYERSETTINGS ) ) { // make races selectable for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); i++ ) (*i).SetRace( (*i).GetRace( ) | SLOTRACE_SELECTABLE ); } } } else
void TracePC::PrintCoverage() { if (!EF->__sanitizer_symbolize_pc || !EF->__sanitizer_get_module_and_offset_for_pc) { Printf("INFO: __sanitizer_symbolize_pc or " "__sanitizer_get_module_and_offset_for_pc is not available," " not printing coverage\n"); return; } std::map<std::string, std::vector<uintptr_t>> CoveredPCsPerModule; std::map<std::string, uintptr_t> ModuleOffsets; std::set<std::string> CoveredDirs, CoveredFiles, CoveredFunctions, CoveredLines; Printf("COVERAGE:\n"); for (size_t i = 1; i < GetNumPCs(); i++) { if (!PCs[i]) continue; std::string FileStr = DescribePC("%s", PCs[i]); if (!IsInterestingCoverageFile(FileStr)) continue; std::string FixedPCStr = DescribePC("%p", PCs[i]); std::string FunctionStr = DescribePC("%F", PCs[i]); std::string LineStr = DescribePC("%l", PCs[i]); char ModulePathRaw[4096] = ""; // What's PATH_MAX in portable C++? void *OffsetRaw = nullptr; if (!EF->__sanitizer_get_module_and_offset_for_pc( reinterpret_cast<void *>(PCs[i]), ModulePathRaw, sizeof(ModulePathRaw), &OffsetRaw)) continue; std::string Module = ModulePathRaw; uintptr_t FixedPC = std::stol(FixedPCStr, 0, 16); uintptr_t PcOffset = reinterpret_cast<uintptr_t>(OffsetRaw); ModuleOffsets[Module] = FixedPC - PcOffset; CoveredPCsPerModule[Module].push_back(PcOffset); CoveredFunctions.insert(FunctionStr); CoveredFiles.insert(FileStr); CoveredDirs.insert(DirName(FileStr)); if (!CoveredLines.insert(FileStr + ":" + LineStr).second) continue; Printf("COVERED: %s %s:%s\n", FunctionStr.c_str(), FileStr.c_str(), LineStr.c_str()); } std::string CoveredDirsStr; for (auto &Dir : CoveredDirs) { if (!CoveredDirsStr.empty()) CoveredDirsStr += ","; CoveredDirsStr += Dir; } Printf("COVERED_DIRS: %s\n", CoveredDirsStr.c_str()); for (auto &M : CoveredPCsPerModule) { std::set<std::string> UncoveredFiles, UncoveredFunctions; std::map<std::string, std::set<int> > UncoveredLines; // Func+File => lines auto &ModuleName = M.first; auto &CoveredOffsets = M.second; uintptr_t ModuleOffset = ModuleOffsets[ModuleName]; std::sort(CoveredOffsets.begin(), CoveredOffsets.end()); Printf("MODULE_WITH_COVERAGE: %s\n", ModuleName.c_str()); // sancov does not yet fully support DSOs. // std::string Cmd = "sancov -print-coverage-pcs " + ModuleName; std::string Cmd = "objdump -d " + ModuleName + " | grep 'call.*__sanitizer_cov_trace_pc_guard' | awk -F: '{print $1}'"; std::string SanCovOutput; if (!ExecuteCommandAndReadOutput(Cmd, &SanCovOutput)) { Printf("INFO: Command failed: %s\n", Cmd.c_str()); continue; } std::istringstream ISS(SanCovOutput); std::string S; while (std::getline(ISS, S, '\n')) { uintptr_t PcOffset = std::stol(S, 0, 16); if (!std::binary_search(CoveredOffsets.begin(), CoveredOffsets.end(), PcOffset)) { uintptr_t PC = ModuleOffset + PcOffset; auto FileStr = DescribePC("%s", PC); if (!IsInterestingCoverageFile(FileStr)) continue; if (CoveredFiles.count(FileStr) == 0) { UncoveredFiles.insert(FileStr); continue; } auto FunctionStr = DescribePC("%F", PC); if (CoveredFunctions.count(FunctionStr) == 0) { UncoveredFunctions.insert(FunctionStr); continue; } std::string LineStr = DescribePC("%l", PC); uintptr_t Line = std::stoi(LineStr); std::string FileLineStr = FileStr + ":" + LineStr; if (CoveredLines.count(FileLineStr) == 0) UncoveredLines[FunctionStr + " " + FileStr].insert(Line); } } for (auto &FileLine: UncoveredLines) for (int Line : FileLine.second) Printf("UNCOVERED_LINE: %s:%d\n", FileLine.first.c_str(), Line); for (auto &Func : UncoveredFunctions) Printf("UNCOVERED_FUNC: %s\n", Func.c_str()); for (auto &File : UncoveredFiles) Printf("UNCOVERED_FILE: %s\n", File.c_str()); } }
void CReplay :: ParseReplay( bool parseBlocks ) { m_HostPID = 0; m_HostName.clear( ); m_GameName.clear( ); m_StatString.clear( ); m_PlayerCount = 0; m_MapGameType = 0; m_Players.clear( ); m_Slots.clear( ); m_RandomSeed = 0; m_SelectMode = 0; m_StartSpotCount = 0; m_LoadingBlocks = queue<BYTEARRAY>( ); m_Blocks = queue<BYTEARRAY>( ); m_CheckSums = queue<uint32_t>( ); if( m_Flags != 32768 ) { CONSOLE_Print( "[REPLAY] invalid replay (flags mismatch)" ); m_Valid = false; return; } istringstream ISS( m_Decompressed ); unsigned char Garbage1; uint32_t Garbage4; string GarbageString; unsigned char GarbageData[65535]; READB( ISS, &Garbage4, 4 ); // Unknown (4.0) if( Garbage4 != 272 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.0 Unknown mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage1, 1 ); // Host RecordID (4.1) if( Garbage1 != 0 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host RecordID mismatch)" ); m_Valid = false; return; } READB( ISS, &m_HostPID, 1 ); if( m_HostPID > 15 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host PlayerID is invalid)" ); m_Valid = false; return; } READSTR( ISS, m_HostName ); // Host PlayerName (4.1) READB( ISS, &Garbage1, 1 ); // Host AdditionalSize (4.1) if( Garbage1 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host AdditionalSize mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage1, 1 ); // Host AdditionalData (4.1) if( Garbage1 != 0 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host AdditionalData mismatch)" ); m_Valid = false; return; } AddPlayer( m_HostPID, m_HostName ); READSTR( ISS, m_GameName ); // GameName (4.2) READSTR( ISS, GarbageString ); // Null (4.0) READSTR( ISS, m_StatString ); // StatString (4.3) READB( ISS, &m_PlayerCount, 4 ); // PlayerCount (4.6) if( m_PlayerCount > 12 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.6 PlayerCount is invalid)" ); m_Valid = false; return; } READB( ISS, &m_MapGameType, 4 ); // GameType (4.7) READB( ISS, &Garbage4, 4 ); // LanguageID (4.8) while( 1 ) { READB( ISS, &Garbage1, 1 ); // Player RecordID (4.1) if( Garbage1 == 22 ) { unsigned char PlayerID; string PlayerName; READB( ISS, &PlayerID, 1 ); // Player PlayerID (4.1) if( PlayerID > 15 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player PlayerID is invalid)" ); m_Valid = false; return; } READSTR( ISS, PlayerName ); // Player PlayerName (4.1) READB( ISS, &Garbage1, 1 ); // Player AdditionalSize (4.1) if( Garbage1 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player AdditionalSize mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage1, 1 ); // Player AdditionalData (4.1) if( Garbage1 != 0 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player AdditionalData mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage4, 4 ); // Unknown if( Garbage4 != 0 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Unknown mismatch)" ); m_Valid = false; return; } AddPlayer( PlayerID, PlayerName ); } else if( Garbage1 == 25 ) break; else { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player RecordID mismatch)" ); m_Valid = false; return; } } uint16_t Size; unsigned char NumSlots; READB( ISS, &Size, 2 ); // Size (4.10) READB( ISS, &NumSlots, 1 ); // NumSlots (4.10) if( Size != 7 + NumSlots * 9 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.10 Size is invalid)" ); m_Valid = false; return; } if( NumSlots == 0 || NumSlots > 12 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.10 NumSlots is invalid)" ); m_Valid = false; return; } for( int i = 0; i < NumSlots; ++i ) { unsigned char SlotData[9]; READB( ISS, SlotData, 9 ); BYTEARRAY SlotDataBA = UTIL_CreateByteArray( SlotData, 9 ); m_Slots.push_back( CGameSlot( SlotDataBA ) ); } READB( ISS, &m_RandomSeed, 4 ); // RandomSeed (4.10) READB( ISS, &m_SelectMode, 1 ); // SelectMode (4.10) READB( ISS, &m_StartSpotCount, 1 ); // StartSpotCount (4.10) if( ISS.eof( ) || ISS.fail( ) ) { CONSOLE_Print( "[SAVEGAME] failed to parse replay header" ); m_Valid = false; return; } if( !parseBlocks ) return; READB( ISS, &Garbage1, 1 ); // first start block ID (5.0) if( Garbage1 != CReplay :: REPLAY_FIRSTSTARTBLOCK ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 first start block ID mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage4, 4 ); // first start block data (5.0) if( Garbage4 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 first start block data mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage1, 1 ); // second start block ID (5.0) if( Garbage1 != CReplay :: REPLAY_SECONDSTARTBLOCK ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 second start block ID mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage4, 4 ); // second start block data (5.0) if( Garbage4 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 second start block data mismatch)" ); m_Valid = false; return; } while( 1 ) { READB( ISS, &Garbage1, 1 ); // third start block ID *or* loading block ID (5.0) if( ISS.eof( ) || ISS.fail( ) ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 third start block unexpected end of file found)" ); m_Valid = false; return; } if( Garbage1 == CReplay :: REPLAY_LEAVEGAME ) { READB( ISS, GarbageData, 13 ); BYTEARRAY LoadingBlock; LoadingBlock.push_back( Garbage1 ); UTIL_AppendByteArray( LoadingBlock, GarbageData, 13 ); m_LoadingBlocks.push( LoadingBlock ); } else if( Garbage1 == CReplay :: REPLAY_THIRDSTARTBLOCK ) break; else { CONSOLE_Print( "[REPLAY] invalid replay (5.0 third start block ID mismatch)" ); m_Valid = false; return; } } READB( ISS, &Garbage4, 4 ); // third start block data (5.0) if( Garbage4 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 third start block data mismatch)" ); m_Valid = false; return; } if( ISS.eof( ) || ISS.fail( ) ) { CONSOLE_Print( "[SAVEGAME] failed to parse replay start blocks" ); m_Valid = false; return; } uint32_t ActualReplayLength = 0; while( 1 ) { READB( ISS, &Garbage1, 1 ); // block ID (5.0) if( ISS.eof( ) || ISS.fail( ) ) break; else if( Garbage1 == CReplay :: REPLAY_LEAVEGAME ) { READB( ISS, GarbageData, 13 ); // reconstruct the block BYTEARRAY Block; Block.push_back( CReplay :: REPLAY_LEAVEGAME ); UTIL_AppendByteArray( Block, GarbageData, 13 ); m_Blocks.push( Block ); } else if( Garbage1 == CReplay :: REPLAY_TIMESLOT ) { uint16_t BlockSize; READB( ISS, &BlockSize, 2 ); READB( ISS, GarbageData, BlockSize ); if( BlockSize >= 2 ) ActualReplayLength += GarbageData[0] | GarbageData[1] << 8; // reconstruct the block BYTEARRAY Block; Block.push_back( CReplay :: REPLAY_TIMESLOT ); UTIL_AppendByteArray( Block, BlockSize, false ); UTIL_AppendByteArray( Block, GarbageData, BlockSize ); m_Blocks.push( Block ); } else if( Garbage1 == CReplay :: REPLAY_CHATMESSAGE ) { unsigned char PID; uint16_t BlockSize; READB( ISS, &PID, 1 ); if( PID > 15 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 chatmessage pid is invalid)" ); m_Valid = false; return; } READB( ISS, &BlockSize, 2 ); READB( ISS, GarbageData, BlockSize ); // reconstruct the block BYTEARRAY Block; Block.push_back( CReplay :: REPLAY_CHATMESSAGE ); Block.push_back( PID ); UTIL_AppendByteArray( Block, BlockSize, false ); UTIL_AppendByteArray( Block, GarbageData, BlockSize ); m_Blocks.push( Block ); } else if( Garbage1 == CReplay :: REPLAY_CHECKSUM ) { READB( ISS, &Garbage1, 1 ); if( Garbage1 != 4 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 checksum unknown mismatch)" ); m_Valid = false; return; } uint32_t CheckSum; READB( ISS, &CheckSum, 4 ); m_CheckSums.push( CheckSum ); } else { // it's not necessarily an error if we encounter an unknown block ID since replays can contain extra data break; } } if( m_ReplayLength != ActualReplayLength ) CONSOLE_Print( "[REPLAY] warning - replay length mismatch (" + UTIL_ToString( m_ReplayLength ) + "ms/" + UTIL_ToString( ActualReplayLength ) + "ms)" ); m_Valid = true; }
void CSaveGame :: ParseSaveGame( ) { m_MapPath.clear( ); m_GameName.clear( ); m_NumSlots = 0; m_Slots.clear( ); m_RandomSeed = 0; m_MagicNumber.clear( ); if( m_Flags != 0 ) { CONSOLE_Print( "[SAVEGAME] invalid replay (flags mismatch)" ); m_Valid = false; return; } istringstream ISS( m_Decompressed ); // savegame format figured out by Varlock: // string -> map path // 0 (string?) -> ??? (no idea what this is) // string -> game name // 0 (string?) -> ??? (maybe original game password) // string -> stat string // 4 bytes -> ??? (seems to be # of slots) // 4 bytes -> ??? (seems to be 0x01 0x28 0x49 0x00 on both of the savegames examined) // 2 bytes -> ??? (no idea what this is) // slot structure // 4 bytes -> magic number unsigned char Garbage1; uint16_t Garbage2; uint32_t Garbage4; string GarbageString; uint32_t MagicNumber; READSTR( ISS, m_MapPath ); // map path READSTR( ISS, GarbageString ); // ??? READSTR( ISS, m_GameName ); // game name READSTR( ISS, GarbageString ); // ??? READSTR( ISS, GarbageString ); // stat string READB( ISS, &Garbage4, 4 ); // ??? READB( ISS, &Garbage4, 4 ); // ??? READB( ISS, &Garbage2, 2 ); // ??? READB( ISS, &m_NumSlots, 1 ); // number of slots if( m_NumSlots > 12 ) { CONSOLE_Print( "[SAVEGAME] invalid savegame (too many slots)" ); m_Valid = false; return; } for( unsigned char i = 0; i < m_NumSlots; i++ ) { unsigned char SlotData[9]; READB( ISS, SlotData, 9 ); // slot data m_Slots.push_back( CGameSlot( SlotData[0], SlotData[1], SlotData[2], SlotData[3], SlotData[4], SlotData[5], SlotData[6], SlotData[7], SlotData[8] ) ); } READB( ISS, &m_RandomSeed, 4 ); // random seed READB( ISS, &Garbage1, 1 ); // GameType READB( ISS, &Garbage1, 1 ); // number of player slots (non observer) READB( ISS, &MagicNumber, 4 ); // magic number if( ISS.eof( ) || ISS.fail( ) ) { CONSOLE_Print( "[SAVEGAME] failed to parse savegame header" ); m_Valid = false; return; } m_MagicNumber = UTIL_CreateByteArray( MagicNumber, false ); m_Valid = true; }