Ensure directories are always listed in deterministic order

macOS APIs have recently changed and do not return sorted entries for directories.
This commit is contained in:
Pierre-Olivier Latour
2019-01-03 15:59:28 -08:00
parent 71e972084c
commit c46a2ddb22
3 changed files with 12 additions and 12 deletions

View File

@ -546,7 +546,7 @@ static inline xmlNodePtr _XMLChildWithName(xmlNodePtr child, const xmlChar* name
NSArray* items = nil; NSArray* items = nil;
if (isDirectory) { if (isDirectory) {
NSError* error = nil; NSError* error = nil;
items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:absolutePath error:&error]; items = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:absolutePath error:&error] sortedArrayUsingSelector:@selector(localizedStandardCompare:)];
if (items == nil) { if (items == nil) {
return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed listing directory \"%@\"", relativePath]; return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed listing directory \"%@\"", relativePath];
} }

View File

@ -981,29 +981,29 @@ static inline NSString* _EncodeBase64(NSString* string) {
} }
- (GCDWebServerResponse*)_responseWithContentsOfDirectory:(NSString*)path { - (GCDWebServerResponse*)_responseWithContentsOfDirectory:(NSString*)path {
NSDirectoryEnumerator* enumerator = [[NSFileManager defaultManager] enumeratorAtPath:path]; NSArray* contents = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL] sortedArrayUsingSelector:@selector(localizedStandardCompare:)];
if (enumerator == nil) { if (contents == nil) {
return nil; return nil;
} }
NSMutableString* html = [NSMutableString string]; NSMutableString* html = [NSMutableString string];
[html appendString:@"<!DOCTYPE html>\n"]; [html appendString:@"<!DOCTYPE html>\n"];
[html appendString:@"<html><head><meta charset=\"utf-8\"></head><body>\n"]; [html appendString:@"<html><head><meta charset=\"utf-8\"></head><body>\n"];
[html appendString:@"<ul>\n"]; [html appendString:@"<ul>\n"];
for (NSString* file in enumerator) { for (NSString* entry in contents) {
if (![file hasPrefix:@"."]) { if (![entry hasPrefix:@"."]) {
NSString* type = [[enumerator fileAttributes] objectForKey:NSFileType]; NSString* type = [[[NSFileManager defaultManager] attributesOfItemAtPath:[path stringByAppendingPathComponent:entry] error:NULL] objectForKey:NSFileType];
GWS_DCHECK(type);
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSString* escapedFile = [file stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString* escapedFile = [entry stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
#pragma clang diagnostic pop #pragma clang diagnostic pop
GWS_DCHECK(escapedFile); GWS_DCHECK(escapedFile);
if ([type isEqualToString:NSFileTypeRegular]) { if ([type isEqualToString:NSFileTypeRegular]) {
[html appendFormat:@"<li><a href=\"%@\">%@</a></li>\n", escapedFile, file]; [html appendFormat:@"<li><a href=\"%@\">%@</a></li>\n", escapedFile, entry];
} else if ([type isEqualToString:NSFileTypeDirectory]) { } else if ([type isEqualToString:NSFileTypeDirectory]) {
[html appendFormat:@"<li><a href=\"%@/\">%@/</a></li>\n", escapedFile, file]; [html appendFormat:@"<li><a href=\"%@/\">%@/</a></li>\n", escapedFile, entry];
} }
} }
[enumerator skipDescendents];
} }
[html appendString:@"</ul>\n"]; [html appendString:@"</ul>\n"];
[html appendString:@"</body></html>\n"]; [html appendString:@"</body></html>\n"];
@ -1176,7 +1176,7 @@ static void _LogResult(NSString* format, ...) {
_ExecuteMainThreadRunLoopSources(); _ExecuteMainThreadRunLoopSources();
result = 0; result = 0;
NSArray* files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL]; NSArray* files = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL] sortedArrayUsingSelector:@selector(localizedStandardCompare:)];
for (NSString* requestFile in files) { for (NSString* requestFile in files) {
if (![requestFile hasSuffix:@".request"]) { if (![requestFile hasSuffix:@".request"]) {
continue; continue;

View File

@ -239,7 +239,7 @@ NS_ASSUME_NONNULL_END
} }
NSError* error = nil; NSError* error = nil;
NSArray* contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:absolutePath error:&error]; NSArray* contents = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:absolutePath error:&error] sortedArrayUsingSelector:@selector(localizedStandardCompare:)];
if (contents == nil) { if (contents == nil) {
return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed listing directory \"%@\"", relativePath]; return [GCDWebServerErrorResponse responseWithServerError:kGCDWebServerHTTPStatusCode_InternalServerError underlyingError:error message:@"Failed listing directory \"%@\"", relativePath];
} }