Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// Copyright 2019 Google
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
 
15
#import "Crashlytics/Shared/FIRCLSMachO/FIRCLSMachOBinary.h"
16
 
17
#import "Crashlytics/Shared/FIRCLSMachO/FIRCLSMachOSlice.h"
18
 
19
#import <CommonCrypto/CommonHMAC.h>
20
 
21
static void FIRCLSSafeHexToString(const uint8_t* value, size_t length, char* outputBuffer);
22
static NSString* FIRCLSNSDataToNSString(NSData* data);
23
static NSString* FIRCLSHashBytes(const void* bytes, size_t length);
24
static NSString* FIRCLSHashNSString(NSString* value);
25
 
26
@interface FIRCLSMachOBinary ()
27
 
28
+ (NSString*)hashNSString:(NSString*)value;
29
 
30
@end
31
 
32
@implementation FIRCLSMachOBinary
33
 
34
+ (id)MachOBinaryWithPath:(NSString*)path {
35
  return [[self alloc] initWithURL:[NSURL fileURLWithPath:path]];
36
}
37
 
38
@synthesize slices = _slices;
39
 
40
- (id)initWithURL:(NSURL*)url {
41
  self = [super init];
42
  if (self) {
43
    _url = [url copy];
44
 
45
    if (!FIRCLSMachOFileInitWithPath(&_file, [[_url path] fileSystemRepresentation])) {
46
      return nil;
47
    }
48
 
49
    _slices = [NSMutableArray new];
50
    FIRCLSMachOFileEnumerateSlices(&_file, ^(FIRCLSMachOSliceRef slice) {
51
      FIRCLSMachOSlice* sliceObject;
52
 
53
      sliceObject = [[FIRCLSMachOSlice alloc] initWithSlice:slice];
54
 
55
      [self->_slices addObject:sliceObject];
56
    });
57
  }
58
 
59
  return self;
60
}
61
 
62
- (void)dealloc {
63
  FIRCLSMachOFileDestroy(&_file);
64
}
65
 
66
- (NSURL*)URL {
67
  return _url;
68
}
69
 
70
- (NSString*)path {
71
  return [_url path];
72
}
73
 
74
- (NSString*)instanceIdentifier {
75
  if (_instanceIdentifier) {
76
    return _instanceIdentifier;
77
  }
78
 
79
  NSMutableString* prehashedString = [NSMutableString new];
80
 
81
  // sort the slices by architecture
82
  NSArray* sortedSlices =
83
      [_slices sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
84
        return [[obj1 architectureName] compare:[obj2 architectureName]];
85
      }];
86
 
87
  // append them all into a big string
88
  for (FIRCLSMachOSlice* slice in sortedSlices) {
89
    [prehashedString appendString:[slice uuid]];
90
  }
91
 
92
  _instanceIdentifier = [FIRCLSHashNSString(prehashedString) copy];
93
 
94
  return _instanceIdentifier;
95
}
96
 
97
- (void)enumerateUUIDs:(void (^)(NSString* uuid, NSString* architecture))block {
98
  for (FIRCLSMachOSlice* slice in _slices) {
99
    block([slice uuid], [slice architectureName]);
100
  }
101
}
102
 
103
- (FIRCLSMachOSlice*)sliceForArchitecture:(NSString*)architecture {
104
  for (FIRCLSMachOSlice* slice in [self slices]) {
105
    if ([[slice architectureName] isEqualToString:architecture]) {
106
      return slice;
107
    }
108
  }
109
 
110
  return nil;
111
}
112
 
113
+ (NSString*)hashNSString:(NSString*)value {
114
  return FIRCLSHashNSString(value);
115
}
116
 
117
@end
118
 
119
// TODO: Functions copied from the SDK.  We should figure out a way to share this.
120
static void FIRCLSSafeHexToString(const uint8_t* value, size_t length, char* outputBuffer) {
121
  const char hex[] = "0123456789abcdef";
122
 
123
  if (!value) {
124
    outputBuffer[0] = '\0';
125
    return;
126
  }
127
 
128
  for (size_t i = 0; i < length; ++i) {
129
    unsigned char c = value[i];
130
    outputBuffer[i * 2] = hex[c >> 4];
131
    outputBuffer[i * 2 + 1] = hex[c & 0x0F];
132
  }
133
 
134
  outputBuffer[length * 2] = '\0';  // null terminate
135
}
136
 
137
static NSString* FIRCLSNSDataToNSString(NSData* data) {
138
  NSString* string;
139
  char* buffer;
140
  size_t size;
141
  NSUInteger length;
142
 
143
  // we need 2 hex char for every byte of data, plus one more spot for a
144
  // null terminator
145
  length = [data length];
146
  size = (length * 2) + 1;
147
  buffer = malloc(sizeof(char) * size);
148
 
149
  if (!buffer) {
150
    return nil;
151
  }
152
 
153
  FIRCLSSafeHexToString([data bytes], length, buffer);
154
 
155
  string = [NSString stringWithUTF8String:buffer];
156
 
157
  free(buffer);
158
 
159
  return string;
160
}
161
 
162
static NSString* FIRCLSHashBytes(const void* bytes, size_t length) {
163
  uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0};
164
  CC_SHA1(bytes, (CC_LONG)length, digest);
165
 
166
  NSData* result = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
167
 
168
  return FIRCLSNSDataToNSString(result);
169
}
170
 
171
static NSString* FIRCLSHashNSString(NSString* value) {
172
  const char* s = [value cStringUsingEncoding:NSUTF8StringEncoding];
173
 
174
  return FIRCLSHashBytes(s, strlen(s));
175
}