mirror of https://github.com/opa334/TrollStore.git
1.3.3
This commit is contained in:
parent
97726b53aa
commit
636419ee53
12
README.md
12
README.md
|
@ -157,17 +157,7 @@ When your app is not sandboxed, you can spawn other binaries using posix_spawn,
|
||||||
<true/>
|
<true/>
|
||||||
```
|
```
|
||||||
|
|
||||||
Because a root binary needs special permissions, you need to specify all your root binaries in the Info.plist of your application like so:
|
You can also add your own binaries into your app bundle.
|
||||||
|
|
||||||
```
|
|
||||||
<key>TSRootBinaries</key>
|
|
||||||
<array>
|
|
||||||
<string>roothelper1</string>
|
|
||||||
<string>some/nested/roothelper</string>
|
|
||||||
</array>
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: The paths in the TSRootBinaries array are relative to the location of the Info.plist, you can also include this key in other bundles such as app plugins.
|
|
||||||
|
|
||||||
Afterwards you can use the [spawnRoot function in TSUtil.m](./Shared/TSUtil.m#L74) to spawn the binary as root.
|
Afterwards you can use the [spawnRoot function in TSUtil.m](./Shared/TSUtil.m#L74) to spawn the binary as root.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Package: com.opa334.trollstoreroothelper
|
Package: com.opa334.trollstoreroothelper
|
||||||
Name: trollstoreroothelper
|
Name: trollstoreroothelper
|
||||||
Version: 1.3.2
|
Version: 1.3.3
|
||||||
Architecture: iphoneos-arm
|
Architecture: iphoneos-arm
|
||||||
Description: An awesome tool of some sort!!
|
Description: An awesome tool of some sort!!
|
||||||
Maintainer: opa334
|
Maintainer: opa334
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#import <objc/runtime.h>
|
#import <objc/runtime.h>
|
||||||
#import <TSUtil.h>
|
#import <TSUtil.h>
|
||||||
#import <sys/utsname.h>
|
#import <sys/utsname.h>
|
||||||
|
#import <mach-o/loader.h>
|
||||||
|
#import <mach-o/fat.h>
|
||||||
|
|
||||||
#import <SpringBoardServices/SpringBoardServices.h>
|
#import <SpringBoardServices/SpringBoardServices.h>
|
||||||
#import <Security/Security.h>
|
#import <Security/Security.h>
|
||||||
|
@ -107,6 +109,51 @@ NSString* appPathForAppId(NSString* appId)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL isMachoFile(NSString* filePath)
|
||||||
|
{
|
||||||
|
FILE* file = fopen(filePath.UTF8String, "r");
|
||||||
|
if(!file) return NO;
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
uint32_t magic;
|
||||||
|
fread(&magic, sizeof(uint32_t), 1, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return magic == FAT_MAGIC || magic == FAT_CIGAM || magic == MH_MAGIC_64 || magic == MH_CIGAM_64;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixPermissionsOfAppBundle(NSString* appBundlePath)
|
||||||
|
{
|
||||||
|
// Apply correct permissions (First run, set everything to 644, owner 33)
|
||||||
|
NSURL* fileURL;
|
||||||
|
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appBundlePath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
|
||||||
|
while(fileURL = [enumerator nextObject])
|
||||||
|
{
|
||||||
|
NSString* filePath = fileURL.path;
|
||||||
|
chown(filePath.UTF8String, 33, 33);
|
||||||
|
chmod(filePath.UTF8String, 0644);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply correct permissions (Second run, set executables and directories to 0755)
|
||||||
|
enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appBundlePath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
|
||||||
|
while(fileURL = [enumerator nextObject])
|
||||||
|
{
|
||||||
|
NSString* filePath = fileURL.path;
|
||||||
|
|
||||||
|
BOOL isDir;
|
||||||
|
[[NSFileManager defaultManager] fileExistsAtPath:fileURL.path isDirectory:&isDir];
|
||||||
|
|
||||||
|
if(isDir || isMachoFile(filePath))
|
||||||
|
{
|
||||||
|
chmod(filePath.UTF8String, 0755);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set .app directory permissions too
|
||||||
|
chmod(appBundlePath.UTF8String, 0755);
|
||||||
|
chown(appBundlePath.UTF8String, 33, 33);
|
||||||
|
}
|
||||||
|
|
||||||
void installLdid(NSString* ldidToCopyPath)
|
void installLdid(NSString* ldidToCopyPath)
|
||||||
{
|
{
|
||||||
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidToCopyPath]) return;
|
if(![[NSFileManager defaultManager] fileExistsAtPath:ldidToCopyPath]) return;
|
||||||
|
@ -386,25 +433,9 @@ int signApp(NSString* appPath)
|
||||||
while(fileURL = [enumerator nextObject])
|
while(fileURL = [enumerator nextObject])
|
||||||
{
|
{
|
||||||
NSString* filePath = fileURL.path;
|
NSString* filePath = fileURL.path;
|
||||||
|
if(isMachoFile(filePath))
|
||||||
BOOL isDir;
|
|
||||||
[[NSFileManager defaultManager] fileExistsAtPath:fileURL.path isDirectory:&isDir];
|
|
||||||
|
|
||||||
if([filePath.lastPathComponent isEqualToString:@"Info.plist"])
|
|
||||||
{
|
{
|
||||||
NSDictionary* infoDictionary = [NSDictionary dictionaryWithContentsOfFile:filePath];
|
storedEntitlements[filePath] = dumpEntitlementsFromBinaryAtPath(filePath);
|
||||||
NSArray* tsRootBinaries = infoDictionary[@"TSRootBinaries"];
|
|
||||||
if(tsRootBinaries && [tsRootBinaries isKindOfClass:[NSArray class]])
|
|
||||||
{
|
|
||||||
for(NSString* rootBinary in tsRootBinaries)
|
|
||||||
{
|
|
||||||
if([rootBinary isKindOfClass:[NSString class]])
|
|
||||||
{
|
|
||||||
NSString* rootBinaryPath = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:rootBinary];
|
|
||||||
storedEntitlements[rootBinaryPath] = dumpEntitlementsFromBinaryAtPath(rootBinaryPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,11 +444,15 @@ int signApp(NSString* appPath)
|
||||||
|
|
||||||
[storedEntitlements enumerateKeysAndObjectsUsingBlock:^(NSString* binaryPath, NSDictionary* entitlements, BOOL* stop)
|
[storedEntitlements enumerateKeysAndObjectsUsingBlock:^(NSString* binaryPath, NSDictionary* entitlements, BOOL* stop)
|
||||||
{
|
{
|
||||||
NSString* tmpEntitlementPlistPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"ent.xml"];
|
NSDictionary* newEntitlements = dumpEntitlementsFromBinaryAtPath(binaryPath);
|
||||||
[entitlements writeToURL:[NSURL fileURLWithPath:tmpEntitlementPlistPath] error:nil];
|
if(!newEntitlements || ![newEntitlements isEqualToDictionary:entitlements])
|
||||||
NSString* tmpEntitlementArg = [@"-S" stringByAppendingString:tmpEntitlementPlistPath];
|
{
|
||||||
runLdid(@[tmpEntitlementArg, certArg, binaryPath], nil, nil);
|
NSString* tmpEntitlementPlistPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"ent.xml"];
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:tmpEntitlementPlistPath error:nil];
|
[entitlements writeToURL:[NSURL fileURLWithPath:tmpEntitlementPlistPath] error:nil];
|
||||||
|
NSString* tmpEntitlementArg = [@"-S" stringByAppendingString:tmpEntitlementPlistPath];
|
||||||
|
runLdid(@[tmpEntitlementArg, certArg, binaryPath], nil, nil);
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:tmpEntitlementPlistPath error:nil];
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,68 +589,7 @@ int installApp(NSString* appPath, BOOL sign, BOOL force)
|
||||||
return 177;
|
return 177;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply correct permissions (First run, set everything to 644, owner 33)
|
fixPermissionsOfAppBundle(appPath);
|
||||||
NSURL* fileURL;
|
|
||||||
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
|
|
||||||
while(fileURL = [enumerator nextObject])
|
|
||||||
{
|
|
||||||
NSString* filePath = fileURL.path;
|
|
||||||
chown(filePath.UTF8String, 33, 33);
|
|
||||||
chmod(filePath.UTF8String, 0644);
|
|
||||||
NSLog(@"[installApp] setting %@ to chown(33,33) chmod(0644)", filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply correct permissions (Second run, set executables and directories to 0755)
|
|
||||||
enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:appPath] includingPropertiesForKeys:nil options:0 errorHandler:nil];
|
|
||||||
while(fileURL = [enumerator nextObject])
|
|
||||||
{
|
|
||||||
NSString* filePath = fileURL.path;
|
|
||||||
|
|
||||||
BOOL isDir;
|
|
||||||
[[NSFileManager defaultManager] fileExistsAtPath:fileURL.path isDirectory:&isDir];
|
|
||||||
|
|
||||||
if([filePath.lastPathComponent isEqualToString:@"Info.plist"])
|
|
||||||
{
|
|
||||||
NSDictionary* infoDictionary = [NSDictionary dictionaryWithContentsOfFile:filePath];
|
|
||||||
NSString* executable = infoDictionary[@"CFBundleExecutable"];
|
|
||||||
if(executable && [executable isKindOfClass:[NSString class]])
|
|
||||||
{
|
|
||||||
NSString* executablePath = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:executable];
|
|
||||||
chmod(executablePath.UTF8String, 0755);
|
|
||||||
NSLog(@"[installApp] applied permissions for bundle executable %@", executablePath);
|
|
||||||
}
|
|
||||||
NSArray* tsRootBinaries = infoDictionary[@"TSRootBinaries"];
|
|
||||||
if(tsRootBinaries && [tsRootBinaries isKindOfClass:[NSArray class]])
|
|
||||||
{
|
|
||||||
for(NSString* rootBinary in tsRootBinaries)
|
|
||||||
{
|
|
||||||
if([rootBinary isKindOfClass:[NSString class]])
|
|
||||||
{
|
|
||||||
NSString* rootBinaryPath = [[filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:rootBinary];
|
|
||||||
if([[NSFileManager defaultManager] fileExistsAtPath:rootBinaryPath])
|
|
||||||
{
|
|
||||||
chmod(rootBinaryPath.UTF8String, 0755);
|
|
||||||
chown(rootBinaryPath.UTF8String, 0, 0);
|
|
||||||
NSLog(@"[installApp] applied permissions for root binary %@", rootBinaryPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(!isDir && [filePath.pathExtension isEqualToString:@"dylib"])
|
|
||||||
{
|
|
||||||
chmod(filePath.UTF8String, 0755);
|
|
||||||
}
|
|
||||||
else if(isDir)
|
|
||||||
{
|
|
||||||
// apparently all dirs are writable by default
|
|
||||||
chmod(filePath.UTF8String, 0755);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set .app directory permissions too
|
|
||||||
chmod(appPath.UTF8String, 0755);
|
|
||||||
chown(appPath.UTF8String, 33, 33);
|
|
||||||
|
|
||||||
// Wipe old version if needed
|
// Wipe old version if needed
|
||||||
if(existed)
|
if(existed)
|
||||||
|
|
|
@ -24,9 +24,10 @@
|
||||||
- (BOOL)registerApplicationDictionary:(NSDictionary*)dict;
|
- (BOOL)registerApplicationDictionary:(NSDictionary*)dict;
|
||||||
- (BOOL)unregisterApplication:(id)arg1;
|
- (BOOL)unregisterApplication:(id)arg1;
|
||||||
- (BOOL)_LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)arg1 internal:(BOOL)arg2 user:(BOOL)arg3;
|
- (BOOL)_LSPrivateRebuildApplicationDatabasesForSystemApps:(BOOL)arg1 internal:(BOOL)arg2 user:(BOOL)arg3;
|
||||||
- (BOOL)uninstallApplication:(NSString*)arg1 withOptions:(id)arg2;
|
|
||||||
- (BOOL)openApplicationWithBundleID:(NSString *)arg1 ;
|
- (BOOL)openApplicationWithBundleID:(NSString *)arg1 ;
|
||||||
- (void)enumerateApplicationsOfType:(NSUInteger)type block:(void (^)(LSApplicationProxy*))block;
|
- (void)enumerateApplicationsOfType:(NSUInteger)type block:(void (^)(LSApplicationProxy*))block;
|
||||||
|
- (BOOL)installApplication:(NSString*)pathToExtractedApp withOptions:(NSDictionary*)options;
|
||||||
|
- (BOOL)uninstallApplication:(NSString*)appId withOptions:(NSDictionary*)options;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface LSEnumerator : NSEnumerator
|
@interface LSEnumerator : NSEnumerator
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
<string>iPhoneOS</string>
|
<string>iPhoneOS</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.3.2</string>
|
<string>1.3.3</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>UIDeviceFamily</key>
|
<key>UIDeviceFamily</key>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Package: com.opa334.trollstorehelper
|
Package: com.opa334.trollstorehelper
|
||||||
Name: TrollStore Helper
|
Name: TrollStore Helper
|
||||||
Version: 1.3.2
|
Version: 1.3.3
|
||||||
Architecture: iphoneos-arm
|
Architecture: iphoneos-arm
|
||||||
Description: Helper utility to install and manage TrollStore!
|
Description: Helper utility to install and manage TrollStore!
|
||||||
Maintainer: opa334
|
Maintainer: opa334
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<string>iPhoneOS</string>
|
<string>iPhoneOS</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.3.2</string>
|
<string>1.3.3</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>UIDeviceFamily</key>
|
<key>UIDeviceFamily</key>
|
||||||
|
@ -188,10 +188,5 @@
|
||||||
</array>
|
</array>
|
||||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>TSRootBinaries</key>
|
|
||||||
<array>
|
|
||||||
<string>trollstorehelper</string>
|
|
||||||
<string>ldid</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -766,20 +766,6 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
|
||||||
NSString* version = [self versionString];
|
NSString* version = [self versionString];
|
||||||
NSString* sizeString = [self sizeString];
|
NSString* sizeString = [self sizeString];
|
||||||
|
|
||||||
// Check if any bundle contains a root binary
|
|
||||||
__block BOOL containsRootBinary = NO;
|
|
||||||
[self enumerateAllInfoDictionaries:^(NSString *key, NSObject *value, BOOL *stop) {
|
|
||||||
if([key isEqualToString:@"TSRootBinaries"])
|
|
||||||
{
|
|
||||||
NSArray* valueArr = (NSArray*)value;
|
|
||||||
if([valueArr isKindOfClass:NSArray.class])
|
|
||||||
{
|
|
||||||
containsRootBinary = valueArr.count;
|
|
||||||
if(containsRootBinary) *stop = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
// Check if any bundles main binary runs unsandboxed
|
// Check if any bundles main binary runs unsandboxed
|
||||||
__block BOOL isUnsandboxed = NO;
|
__block BOOL isUnsandboxed = NO;
|
||||||
[self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) {
|
[self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop) {
|
||||||
|
@ -811,7 +797,7 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
// Check if any bundles main binary can spawn an external binary
|
// Check if any bundles main binary can spawn an external binary
|
||||||
__block BOOL canSpawnBinaries = NO;
|
__block BOOL isPlatformApplication = NO;
|
||||||
[self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop)
|
[self enumerateAllEntitlements:^(NSString *key, NSObject *value, BOOL *stop)
|
||||||
{
|
{
|
||||||
if([key isEqualToString:@"platform-application"])
|
if([key isEqualToString:@"platform-application"])
|
||||||
|
@ -819,8 +805,8 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
|
||||||
NSNumber* valueNum = (NSNumber*)value;
|
NSNumber* valueNum = (NSNumber*)value;
|
||||||
if(valueNum && [valueNum isKindOfClass:NSNumber.class])
|
if(valueNum && [valueNum isKindOfClass:NSNumber.class])
|
||||||
{
|
{
|
||||||
canSpawnBinaries = valueNum.boolValue;
|
isPlatformApplication = valueNum.boolValue;
|
||||||
if(canSpawnBinaries) *stop = YES;
|
if(isPlatformApplication) *stop = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
@ -1072,15 +1058,11 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
|
||||||
}
|
}
|
||||||
|
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nCapabilities" attributes:headerAttributes]];
|
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nCapabilities" attributes:headerAttributes]];
|
||||||
if(containsRootBinary && canSpawnBinaries && hasPersonaMngmt)
|
if(isPlatformApplication && isUnsandboxed && hasPersonaMngmt)
|
||||||
{
|
{
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn its own embedded binaries with root privileges." attributes:bodyDangerAttributes]];
|
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn its own embedded binaries with root privileges." attributes:bodyDangerAttributes]];
|
||||||
}
|
}
|
||||||
else if(canSpawnBinaries && hasPersonaMngmt)
|
else if(isPlatformApplication && isUnsandboxed)
|
||||||
{
|
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn arbitary binaries as root, but does not contain any such binaries by itself." attributes:bodyWarningAttributes]];
|
|
||||||
}
|
|
||||||
else if(canSpawnBinaries)
|
|
||||||
{
|
{
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn arbitary binaries as the mobile user." attributes:bodyWarningAttributes]];
|
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can spawn arbitary binaries as the mobile user." attributes:bodyWarningAttributes]];
|
||||||
}
|
}
|
||||||
|
@ -1092,15 +1074,15 @@ extern UIImage* imageWithSize(UIImage* image, CGSize size);
|
||||||
if(allowedTccServices.count)
|
if(allowedTccServices.count)
|
||||||
{
|
{
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nPrivacy" attributes:headerAttributes]];
|
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nPrivacy" attributes:headerAttributes]];
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access the following services without asking for permission:\n" attributes:bodyDangerAttributes]];
|
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access the following services without asking for permission:\n" attributes:bodyWarningAttributes]];
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedTccServices allObjects]] attributes:bodyAttributes]];
|
[description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedTccServices allObjects]] attributes:bodyWarningAttributes]];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowedMGKeys.count)
|
if (allowedMGKeys.count)
|
||||||
{
|
{
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nDevice Info" attributes:headerAttributes]];
|
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n\nDevice Info" attributes:headerAttributes]];
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access protected information about this device.\n" attributes:bodyWarningAttributes]];
|
[description appendAttributedString:[[NSAttributedString alloc] initWithString:@"\nThe app can access protected information about this device:\n" attributes:bodyWarningAttributes]];
|
||||||
[description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedMGKeys allObjects]] attributes:bodyAttributes]];
|
[description appendAttributedString:[[NSAttributedString alloc] initWithString:[NSListFormatter localizedStringByJoiningStrings:[allowedMGKeys allObjects]] attributes:bodyWarningAttributes]];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unrestrictedContainerAccess || accessibleContainers.count)
|
if(unrestrictedContainerAccess || accessibleContainers.count)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Package: com.opa334.trollstore
|
Package: com.opa334.trollstore
|
||||||
Name: TrollStore
|
Name: TrollStore
|
||||||
Version: 1.3.2
|
Version: 1.3.3
|
||||||
Architecture: iphoneos-arm
|
Architecture: iphoneos-arm
|
||||||
Description: An awesome application!
|
Description: An awesome application!
|
||||||
Maintainer: opa334
|
Maintainer: opa334
|
||||||
|
|
Loading…
Reference in New Issue