-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
.ocTransferIDXXXXX.part makes filename too long #25425 #26978
Changes from 3 commits
388bbc7
371d48e
c6b54c8
8656192
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,7 +111,7 @@ public function put($data) { | |
|
||
if ($needsPartFile) { | ||
// mark file as partial while uploading (ignored by the scanner) | ||
$partFilePath = $this->getPartFileBasePath($this->path) . '.ocTransferId' . rand() . '.part'; | ||
$partFilePath = sha1($this->getPartFileBasePath($this->path)) . '.ocTransferId' . rand() . '.part'; | ||
} else { | ||
// upload file directly as the final path | ||
$partFilePath = $this->path; | ||
|
@@ -427,12 +427,11 @@ private function createFileChunked($data) { | |
list($targetStorage, $targetInternalPath) = $this->fileView->resolvePath($targetPath); | ||
|
||
if ($needsPartFile) { | ||
// we first assembly the target file as a part file | ||
$partFile = $this->getPartFileBasePath($path . '/' . $info['name']) . '.ocTransferId' . $info['transferid'] . '.part'; | ||
// we first assemble the target file as a part file | ||
$partFile = $this->getPartFileBasePath($path . '/' . sha1($info['name'])) . '.ocTransferId' . $info['transferid'] . '.part'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so up there you use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @PVince81 I use dirname/basename up there because I can't see another method or context trough which I can obtaine filename and path in seperated form. On the chunked codepath there is decodeName method which returns a info array wihich contains the filename only. |
||
/** @var \OC\Files\Storage\Storage $targetStorage */ | ||
list($partStorage, $partInternalPath) = $this->fileView->resolvePath($partFile); | ||
|
||
|
||
$chunk_handler->file_assemble($partStorage, $partInternalPath); | ||
|
||
// here is the final atomic rename | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1002,4 +1002,87 @@ public function testGetFopenThrows() { | |
|
||
$file->get(); | ||
} | ||
|
||
public function testPutCreatesPartFile() { | ||
$stream = $this->getStream('ABCDEFG'); | ||
$storage = $this->getMockBuilder(Local::class) | ||
->setMethods(['fopen', 'moveFromStorage', 'file_exists']) | ||
->setConstructorArgs([['datadir' => \OC::$server->getTempManager()->getTemporaryFolder()]]) | ||
->getMock(); | ||
|
||
$storage->expects($this->atLeastOnce()) | ||
->method('fopen') | ||
->with($this->matchesRegularExpression('/^([0-9a-f]{40})(.ocTransferId)([0-9]+)(.part)$/i')) | ||
->willReturn($stream); | ||
|
||
$storage->method('moveFromStorage') | ||
->willReturn(true); | ||
|
||
$storage->method('file_exists') | ||
->willReturn(true); | ||
|
||
|
||
$path = '/' . $this->user . '/files'; | ||
$info = new FileInfo($path, $this->getMockStorage(), null, [ | ||
'permissions' => Constants::PERMISSION_ALL | ||
], null); | ||
|
||
$view = $this->getMockBuilder(View::class) | ||
->setMethods(['fopen', 'resolvePath']) | ||
->getMock(); | ||
|
||
|
||
$view->expects($this->atLeastOnce()) | ||
->method('resolvePath') | ||
->will($this->returnCallback( | ||
function ($path) use ($storage) { | ||
return [$storage, $path]; | ||
} | ||
)); | ||
|
||
$file = new File($view, $info); | ||
$file->put($stream); | ||
} | ||
|
||
public function testPutWithChunkCreatesPartFile() { | ||
$stream = $this->getStream('ABCDEFG'); | ||
|
||
$storage = $this->getMockBuilder(Local::class) | ||
->setMethods(['fopen', 'moveFromStorage', 'file_exists']) | ||
->setConstructorArgs([['datadir' => \OC::$server->getTempManager()->getTemporaryFolder()]]) | ||
->getMock(); | ||
|
||
$storage->expects($this->atLeastOnce()) | ||
->method('fopen') | ||
->with($this->matchesRegularExpression('/^(\/[0-9a-f]{40})(.ocTransferId)([0-9]+)(.part)$/i')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a hard-coded result would have been fine too and easier to understand, considering that the input is also hard-coded There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @PVince81 The result isn't entirely static because .ocTransferID is internally generated by rand() but I could still simplify the regex by making the hash-part static. |
||
->willReturn($this->getStream('FOO1231')); | ||
|
||
$path = 'foo.dat-chunking-13242432-0-0'; | ||
|
||
$info = new FileInfo($path, $this->getMockStorage(), null, [ | ||
'permissions' => Constants::PERMISSION_ALL | ||
], null); | ||
$info['checksum'] = 'abcdefg123'; | ||
$info['etag'] = 'deadbeef1337'; | ||
|
||
$view = $this->getMockBuilder(View::class) | ||
->setMethods(['fopen', 'resolvePath', 'getFileInfo']) | ||
->getMock(); | ||
|
||
$view->method('getFileInfo') | ||
->willReturn($info); | ||
|
||
$view->expects($this->atLeastOnce()) | ||
->method('resolvePath') | ||
->will($this->returnCallback( | ||
function ($path) use ($storage) { | ||
return [$storage, $path]; | ||
} | ||
)); | ||
|
||
|
||
$_SERVER['HTTP_OC_CHUNKED'] = true; | ||
$file = new File($view, $info); | ||
$file->put($stream); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Split the
$this->path
and use thesha1
of its basename because we don't want to hash the whole path