using ptr_smart to clean up memory in case of exception

This commit is contained in:
tihmstar 2016-09-21 22:48:30 +02:00
parent 673209626e
commit b468f1fae0
3 changed files with 27 additions and 9 deletions

View file

@ -91,8 +91,10 @@ void futurerestore::putDeviceIntoRecovery(){
reterror(-3, "unsupported devicemode, please put device in recovery mode or normal mode\n");
}
free(_client->udid);
_client->udid = NULL;
//only needs to be freed manually when function did't throw exception
safeFree(_client->udid);
//these get also freed by destructor
normal_client_free(_client);
recovery_client_free(_client);
}
@ -181,7 +183,7 @@ void futurerestore::loadAPTicket(const char *apticketPath){
else
plist_from_xml(buf, (uint32_t)fSize, &_apticket);
if (_im4m) free(_im4m);
safeFree(_im4m);
plist_t ticket = plist_dict_get_item(_apticket, "ApImg4Ticket");
uint64_t im4msize=0;
@ -194,6 +196,7 @@ void futurerestore::loadAPTicket(string apticketPath){
int futurerestore::doRestore(const char *ipsw, bool noerase){
int err = 0;
//some memory might not get freed if this function throws an exception, but you probably don't want to catch that anyway.
struct idevicerestore_client_t* client = _client;
int unused;
@ -452,6 +455,8 @@ error:
futurerestore::~futurerestore(){
normal_client_free(_client);
recovery_client_free(_client);
idevicerestore_client_free(_client);
safeFree(_im4m);
safeFree(_firmwareJson);
@ -506,9 +511,11 @@ char *futurerestore::getLatestManifest(){
if (versions) free(versions[versionCnt-1]),free(versions);
__latestFirmwareUrl = getFirmwareUrl(device, versVals, _firmwareJson, _firmwareTokens);
if (!__latestFirmwareUrl) reterror(-21, "could not find url of latest firmware\n");
if (!__latestFirmwareUrl) free((char*)versVals.version),reterror(-21, "could not find url of latest firmware\n");
__latestManifest = getBuildManifest(__latestFirmwareUrl, device, versVals.version, 0);
if (!__latestManifest) reterror(-22, "could not get buildmanifest of latest firmware\n");
if (!__latestManifest) free((char*)versVals.version),reterror(-22, "could not get buildmanifest of latest firmware\n");
free((char*)versVals.version);
}
@ -642,11 +649,11 @@ plist_t futurerestore::loadPlistFromFile(const char *path){
char *futurerestore::getPathOfElementInManifest(const char *element, const char *manifeststr){
char *pathStr = NULL;
ptr_smart<plist_t> buildmanifest(NULL,plist_free);
plist_t buildmanifest;
plist_from_xml(manifeststr, (uint)strlen(manifeststr), &buildmanifest);
if (plist_t buildidentities = plist_dict_get_item(buildmanifest, "BuildIdentities"))
if (plist_t buildidentities = plist_dict_get_item(buildmanifest._p, "BuildIdentities"))
if (plist_t firstIdentitie = plist_array_get_item(buildidentities, 0))
if (plist_t manifest = plist_dict_get_item(firstIdentitie, element))
if (plist_t info = plist_dict_get_item(manifest, "Info"))
@ -655,7 +662,6 @@ char *futurerestore::getPathOfElementInManifest(const char *element, const char
goto noerror;
reterror(-31, "could not get %s path\n",element);
noerror:
plist_free(buildmanifest);
return pathStr;
}

View file

@ -16,6 +16,19 @@
using namespace std;
template <typename T>
class ptr_smart {
function<void(T)> _ptr_free;
public:
T _p;
ptr_smart(T p, function<void(T)> ptr_free){static_assert(is_pointer<T>(), "error: this is for pointers only\n"); _p = p;_ptr_free = ptr_free;}
ptr_smart(T p){this->ptr_smart(p,static_cast<void(*)(T)>(free));}
ptr_smart(){this->ptr_smart(NULL,static_cast<void(*)(T)>(free));}
T operator=(T p){return _p = p;}
T *operator&(){return &_p;}
~ptr_smart(){if (_p) _ptr_free(_p);}
};
class futurerestore {
struct idevicerestore_client_t* _client;
bool _didInit = false;

View file

@ -68,7 +68,6 @@ int main(int argc, const char * argv[]) {
const char *sepPath = NULL;
const char *sepManifestPath = NULL;
t_devicevals devVals;
t_iosVersion versVals;
memset(&devVals, 0, sizeof(devVals));