Skip to content

Commit 6d08f10

Browse files
authored
Add error for attempt to upload directory (#5750)
1 parent abe9e97 commit 6d08f10

File tree

6 files changed

+48
-6
lines changed

6 files changed

+48
-6
lines changed

FirebaseStorage/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# 3.7.0
22
- [fixed] Fixed a crash when listAll() was called at the root location. (#5772)
33

4+
- [added] Added a check to FIRStorageUploadTask's `putFile:` to check if the passed in `fileURL` is a directory, and provides a clear error if it is. (#5750)
5+
46
# 3.6.1
57
- [fixed] Fix a rare case where a StorageTask would call its completion callbacks more than
68
once. (#5245)

FirebaseStorage/Sources/FIRStorageUploadTask.m

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,14 @@ - (BOOL)isContentToUploadValid:(NSError **)outError {
193193
}
194194

195195
NSError *fileReachabilityError;
196-
if (![_fileURL checkResourceIsReachableAndReturnError:&fileReachabilityError]) {
196+
if (![_fileURL checkResourceIsReachableAndReturnError:&fileReachabilityError] ||
197+
![self fileURLisFile:_fileURL]) {
197198
if (outError != NULL) {
198199
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithCapacity:2];
199-
userInfo[NSLocalizedDescriptionKey] =
200-
[NSString stringWithFormat:@"File at URL: %@ is not reachable.", _fileURL.absoluteString];
200+
userInfo[NSLocalizedDescriptionKey] = [NSString
201+
stringWithFormat:@"File at URL: %@ is not reachable. "
202+
@"Ensure file URL is not a directory, symbolic link, or invalid url.",
203+
_fileURL.absoluteString];
201204

202205
if (fileReachabilityError) {
203206
userInfo[NSUnderlyingErrorKey] = fileReachabilityError;
@@ -257,4 +260,12 @@ - (void)resume {
257260
}];
258261
}
259262

263+
#pragma mark - Private Helpers
264+
265+
- (BOOL)fileURLisFile:(NSURL *)fileURL {
266+
NSNumber *isFile = [NSNumber numberWithBool:NO];
267+
[fileURL getResourceValue:&isFile forKey:NSURLIsRegularFileKey error:nil];
268+
return [isFile boolValue];
269+
}
270+
260271
@end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The `HomeImprovement.numbers` directory exists to test Firebase Storage's ability to fail gracefully when one attempts to upload a directory. Since git doesn't track track empty directories. This .txt file exists to provide context and make git track the folder.

FirebaseStorage/Tests/Unit/FIRStorageReferenceTests.m

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ - (void)testReferenceWithNonExistentFileFailsWithCompletion {
180180
XCTAssertEqualObjects(error.domain, FIRStorageErrorDomain);
181181
XCTAssertEqual(error.code, FIRStorageErrorCodeUnknown);
182182
NSString *expectedDescription = [NSString
183-
stringWithFormat:@"File at URL: %@ is not reachable.", dummyFileURL.absoluteString];
183+
stringWithFormat:@"File at URL: %@ is not reachable. "
184+
@"Ensure file URL is not a directory, symbolic link, or invalid url.",
185+
dummyFileURL.absoluteString];
184186
XCTAssertEqualObjects(error.localizedDescription, expectedDescription);
185187
}];
186188

@@ -204,7 +206,10 @@ - (void)testReferenceWithNilFileURLFailsWithCompletion {
204206

205207
XCTAssertEqualObjects(error.domain, FIRStorageErrorDomain);
206208
XCTAssertEqual(error.code, FIRStorageErrorCodeUnknown);
207-
NSString *expectedDescription = @"File at URL: (null) is not reachable.";
209+
NSString *expectedDescription = [NSString
210+
stringWithFormat:@"File at URL: %@ is not reachable. "
211+
@"Ensure file URL is not a directory, symbolic link, or invalid url.",
212+
dummyFileURL.absoluteString];
208213
XCTAssertEqualObjects(error.localizedDescription, expectedDescription);
209214
}];
210215

FirebaseStorageSwift.podspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ Firebase Storage provides robust, secure file uploads and downloads from Firebas
3939
int_tests.requires_app_host = true
4040
# Resources are shared with FirebaseStorage's integration tests.
4141
int_tests.resources = 'FirebaseStorage/Tests/Integration/Resources/1mb.dat',
42-
'FirebaseStorage/Tests/Integration/Resources/GoogleService-Info.plist'
42+
'FirebaseStorage/Tests/Integration/Resources/GoogleService-Info.plist',
43+
'FirebaseStorage/Tests/Integration/Resources/HomeImprovement.numbers'
4344
int_tests.dependency 'FirebaseAuth', '~> 6.5'
4445
end
4546
end

FirebaseStorageSwift/Tests/Integration/StorageIntegration.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,18 @@ class StorageIntegration: XCTestCase {
256256
waitForExpectations()
257257
}
258258

259+
func testAttemptToUploadDirectoryShouldFail() throws {
260+
// This `.numbers` file is actually a directory.
261+
let fileName = "HomeImprovement.numbers"
262+
let bundle = Bundle(for: StorageIntegration.self)
263+
let fileURL = try XCTUnwrap(bundle.url(forResource: fileName, withExtension: ""),
264+
"Failed to get filePath")
265+
let ref = storage.reference(withPath: "ios/public/" + fileName)
266+
ref.putFile(from: fileURL) { result in
267+
self.assertResultFailure(result)
268+
}
269+
}
270+
259271
func testPutFileWithSpecialCharacters() throws {
260272
let expectation = self.expectation(description: #function)
261273

@@ -607,4 +619,14 @@ class StorageIntegration: XCTestCase {
607619
XCTFail("Unexpected error \(error)")
608620
}
609621
}
622+
623+
private func assertResultFailure<T>(_ result: Result<T, Error>,
624+
file: StaticString = #file, line: UInt = #line) {
625+
switch result {
626+
case let .success(value):
627+
XCTFail("Unexpected success with value: \(value)")
628+
case let .failure(error):
629+
XCTAssertNotNil(error, file: file, line: line)
630+
}
631+
}
610632
}

0 commit comments

Comments
 (0)