Skip to content

Commit 3962be4

Browse files
committed
feat: implement function to verify if data is UINibArchive
As can seen here (https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes#Interface-Builder), XIB files is compiled using UINibEncoder to reduce file size and that new NIB files are structured following this format (https://www.mothersruin.com/software/Archaeology/reverse/uinib.html).
1 parent 4a68f33 commit 3962be4

File tree

4 files changed

+105
-10
lines changed

4 files changed

+105
-10
lines changed

src/private-frameworks/UIFoundation/include/UIFoundation/UIFoundation.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@
139139
#import <UIFoundation/NSWordMLReader.h>
140140
#import <UIFoundation/NSWordMLWriter.h>
141141

142+
extern const char *UIArchiveHeaderIdentifier;
143+
extern const uint32_t UIMaximumCompatibleFormatVersion;
144+
extern const uint32_t UICurrentCoderVersion;
145+
142146
void* CFArrayCreateWithNonRetainedObjectsFromNSArray(void);
143147
void* CFDictionaryCreateWithNonRetainedValuesFromNSDictionary(void);
144148
void* NSConvertGlyphsToPackedGlyphs(void);
@@ -150,7 +154,7 @@ void* UIAppendBytesForValueToData(void);
150154
void* UIAppendVInt32ToData(void);
151155
void* UIArrayByKeepingObjectsInSet(void);
152156
void* UICreateOrderedAndStrippedCoderValues(void);
153-
void* UIDataLooksLikeNibArchive(void);
157+
BOOL UIDataLooksLikeNibArchive(NSData *data);
154158
void* UIDistanceBetweenPointAndRect(void);
155159
void* UIFixedByteLengthForType(void);
156160
void* UINibArchiveIndexFromNumber(void);

src/private-frameworks/UIFoundation/include/UIFoundation/UINibDecoder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include <Foundation/Foundation.h>
2121

22-
@interface UINibDecoder : NSObject
22+
@interface UINibDecoder : NSCoder
23+
24+
- (instancetype) initForReadingWithData: (NSData *) data;
2325

2426
@end

src/private-frameworks/UIFoundation/src/UIFoundation.m

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818
*/
1919

20-
2120
#include <UIFoundation/UIFoundation.h>
2221
#include <stdlib.h>
2322
#include <stdio.h>
2423

24+
const char *UIArchiveHeaderIdentifier = "NIBArchive";
25+
const uint32_t UIMaximumCompatibleFormatVersion = 1;
26+
const uint32_t UICurrentCoderVersion = 10;
27+
2528
static int verbose = 0;
2629

2730
__attribute__((constructor))
@@ -95,10 +98,29 @@ static void initme(void) {
9598
return NULL;
9699
}
97100

98-
void* UIDataLooksLikeNibArchive(void)
101+
BOOL UIDataLooksLikeNibArchive(NSData *data)
99102
{
100-
if (verbose) puts("STUB: UIDataLooksLikeNibArchive called");
101-
return NULL;
103+
char headerIdentifier[11];
104+
[data getBytes: headerIdentifier length: 10];
105+
headerIdentifier[10] = '\0';
106+
107+
if (strcmp(headerIdentifier, UIArchiveHeaderIdentifier) != 0) {
108+
return FALSE;
109+
}
110+
111+
const uint32_t formatVersion = *((uint32_t *)[[data subdataWithRange: NSMakeRange(10, sizeof(uint32_t))] bytes]);
112+
113+
if (formatVersion > UIMaximumCompatibleFormatVersion) {
114+
return FALSE;
115+
}
116+
117+
const uint32_t coderVersion = *((uint32_t *)[[data subdataWithRange: NSMakeRange(14, sizeof(uint32_t))] bytes]);
118+
119+
if (coderVersion != UICurrentCoderVersion) {
120+
return FALSE;
121+
}
122+
123+
return TRUE;
102124
}
103125

104126
void* UIDistanceBetweenPointAndRect(void)

src/private-frameworks/UIFoundation/src/UINibDecoder.m

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,81 @@
2121

2222
@implementation UINibDecoder
2323

24-
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
24+
- (instancetype) initForReadingWithData: (NSData *) data
2525
{
26-
return [NSMethodSignature signatureWithObjCTypes: "v@:"];
26+
printf("STUB %s\n", __PRETTY_FUNCTION__);
27+
return self;
2728
}
2829

29-
- (void)forwardInvocation:(NSInvocation *)anInvocation
30+
- (BOOL) containsValueForKey: (NSString *) key
3031
{
31-
NSLog(@"Stub called: %@ in %@", NSStringFromSelector([anInvocation selector]), [self class]);
32+
printf("STUB %s\n", __PRETTY_FUNCTION__);
33+
return NO;
34+
}
35+
36+
- (void) decodeValueOfObjCType: (const char *) type at: (void *) data
37+
{
38+
printf("STUB %s\n", __PRETTY_FUNCTION__);
39+
}
40+
41+
- (NSData *) decodeDataObject
42+
{
43+
printf("STUB %s\n", __PRETTY_FUNCTION__);
44+
return nil;
45+
}
46+
47+
- (id) decodeObjectForKey: (NSString *) key
48+
{
49+
printf("STUB %s\n", __PRETTY_FUNCTION__);
50+
return nil;
51+
}
52+
53+
- (BOOL) decodeBoolForKey: (NSString *) key
54+
{
55+
printf("STUB %s\n", __PRETTY_FUNCTION__);
56+
return NO;
57+
}
58+
59+
- (int) decodeIntForKey:(NSString *) key
60+
{
61+
printf("STUB %s\n", __PRETTY_FUNCTION__);
62+
return 0;
63+
}
64+
65+
- (int32_t) decodeInt32ForKey:(NSString *) key
66+
{
67+
printf("STUB %s\n", __PRETTY_FUNCTION__);
68+
return 0;
69+
}
70+
71+
- (int64_t) decodeInt64ForKey:(NSString *) key
72+
{
73+
printf("STUB %s\n", __PRETTY_FUNCTION__);
74+
return 0;
75+
}
76+
77+
- (float) decodeFloatForKey:(NSString *) key
78+
{
79+
printf("STUB %s\n", __PRETTY_FUNCTION__);
80+
return 0.0f;
81+
}
82+
83+
- (double) decodeDoubleForKey:(NSString *) key
84+
{
85+
printf("STUB %s\n", __PRETTY_FUNCTION__);
86+
return 0.0;
87+
}
88+
89+
- (const uint8_t *) decodeBytesForKey: (NSString *) key returnedLength: (NSUInteger *) len
90+
{
91+
printf("STUB %s\n", __PRETTY_FUNCTION__);
92+
return NULL;
93+
}
94+
95+
- (NSInteger) versionForClassName: (NSString *) className
96+
{
97+
printf("STUB %s\n", __PRETTY_FUNCTION__);
98+
return 0;
3299
}
33100

34101
@end

0 commit comments

Comments
 (0)