Skip to content

Commit 50fc614

Browse files
authored
Merge pull request #54297 from nextcloud/backport/54125/stable31
2 parents 50d982e + cf19200 commit 50fc614

File tree

11 files changed

+135
-83
lines changed

11 files changed

+135
-83
lines changed

apps/dav/lib/Connector/Sabre/File.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ public function put($data) {
201201
}
202202
}
203203

204+
$lengthHeader = $this->request->getHeader('content-length');
205+
$expected = $lengthHeader !== '' ? (int)$lengthHeader : null;
206+
204207
if ($partStorage->instanceOfStorage(IWriteStreamStorage::class)) {
205208
$isEOF = false;
206209
$wrappedData = CallbackWrapper::wrap($data, null, null, null, null, function ($stream) use (&$isEOF): void {
@@ -212,7 +215,7 @@ public function put($data) {
212215
$count = -1;
213216
try {
214217
/** @var IWriteStreamStorage $partStorage */
215-
$count = $partStorage->writeStream($internalPartPath, $wrappedData);
218+
$count = $partStorage->writeStream($internalPartPath, $wrappedData, $expected);
216219
} catch (GenericFileException $e) {
217220
$logger = Server::get(LoggerInterface::class);
218221
$logger->error('Error while writing stream to storage: ' . $e->getMessage(), ['exception' => $e, 'app' => 'webdav']);
@@ -232,10 +235,7 @@ public function put($data) {
232235
[$count, $result] = \OC_Helper::streamCopy($data, $target);
233236
fclose($target);
234237
}
235-
236-
$lengthHeader = $this->request->getHeader('content-length');
237-
$expected = $lengthHeader !== '' ? (int)$lengthHeader : -1;
238-
if ($result === false && $expected >= 0) {
238+
if ($result === false && $expected !== null) {
239239
throw new Exception(
240240
$this->l10n->t(
241241
'Error while copying file to target location (copied: %1$s, expected filesize: %2$s)',
@@ -250,7 +250,7 @@ public function put($data) {
250250
// if content length is sent by client:
251251
// double check if the file was fully received
252252
// compare expected and actual size
253-
if ($expected >= 0
253+
if ($expected !== null
254254
&& $expected !== $count
255255
&& $this->request->getMethod() === 'PUT'
256256
) {

apps/files_external/3rdparty/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
},
1010
"require": {
1111
"icewind/smb": "3.7.0",
12-
"icewind/streams": "0.7.7"
12+
"icewind/streams": "0.7.8"
1313
}
1414
}

apps/files_external/3rdparty/composer.lock

Lines changed: 5 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/files_external/3rdparty/composer/InstalledVersions.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ class InstalledVersions
3232
*/
3333
private static $installed;
3434

35+
/**
36+
* @var bool
37+
*/
38+
private static $installedIsLocalDir;
39+
3540
/**
3641
* @var bool|null
3742
*/
@@ -309,6 +314,12 @@ public static function reload($data)
309314
{
310315
self::$installed = $data;
311316
self::$installedByVendor = array();
317+
318+
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
319+
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
320+
// so we have to assume it does not, and that may result in duplicate data being returned when listing
321+
// all installed packages for example
322+
self::$installedIsLocalDir = false;
312323
}
313324

314325
/**
@@ -322,19 +333,27 @@ private static function getInstalled()
322333
}
323334

324335
$installed = array();
336+
$copiedLocalDir = false;
325337

326338
if (self::$canGetVendors) {
339+
$selfDir = strtr(__DIR__, '\\', '/');
327340
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
341+
$vendorDir = strtr($vendorDir, '\\', '/');
328342
if (isset(self::$installedByVendor[$vendorDir])) {
329343
$installed[] = self::$installedByVendor[$vendorDir];
330344
} elseif (is_file($vendorDir.'/composer/installed.php')) {
331345
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
332346
$required = require $vendorDir.'/composer/installed.php';
333-
$installed[] = self::$installedByVendor[$vendorDir] = $required;
334-
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
335-
self::$installed = $installed[count($installed) - 1];
347+
self::$installedByVendor[$vendorDir] = $required;
348+
$installed[] = $required;
349+
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
350+
self::$installed = $required;
351+
self::$installedIsLocalDir = true;
336352
}
337353
}
354+
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
355+
$copiedLocalDir = true;
356+
}
338357
}
339358
}
340359

@@ -350,7 +369,7 @@ private static function getInstalled()
350369
}
351370
}
352371

353-
if (self::$installed !== array()) {
372+
if (self::$installed !== array() && !$copiedLocalDir) {
354373
$installed[] = self::$installed;
355374
}
356375

apps/files_external/3rdparty/composer/installed.json

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,12 @@
5252
},
5353
{
5454
"name": "icewind/streams",
55-
"version": "v0.7.7",
56-
"version_normalized": "0.7.7.0",
55+
"version": "v0.7.8",
56+
"version_normalized": "0.7.8.0",
5757
"source": {
5858
"type": "git",
59-
"url": "https://github.com/icewind1991/Streams.git",
60-
"reference": "64200fd7cfcc7f550c3c695c48d8fd8bba97fecb"
61-
},
62-
"dist": {
63-
"type": "zip",
64-
"url": "https://api.github.com/repos/icewind1991/Streams/zipball/64200fd7cfcc7f550c3c695c48d8fd8bba97fecb",
65-
"reference": "64200fd7cfcc7f550c3c695c48d8fd8bba97fecb",
66-
"shasum": ""
59+
"url": "https://codeberg.org/icewind/streams",
60+
"reference": "cb2bd3ed41b516efb97e06e8da35a12ef58ba48b"
6761
},
6862
"require": {
6963
"php": ">=7.1"
@@ -73,9 +67,9 @@
7367
"phpstan/phpstan": "^0.12",
7468
"phpunit/phpunit": "^9"
7569
},
76-
"time": "2023-03-16T14:52:25+00:00",
70+
"time": "2024-12-05T14:36:22+00:00",
7771
"type": "library",
78-
"installation-source": "dist",
72+
"installation-source": "source",
7973
"autoload": {
8074
"psr-4": {
8175
"Icewind\\Streams\\": "src/"
@@ -92,10 +86,6 @@
9286
}
9387
],
9488
"description": "A set of generic stream wrappers",
95-
"support": {
96-
"issues": "https://github.com/icewind1991/Streams/issues",
97-
"source": "https://github.com/icewind1991/Streams/tree/v0.7.7"
98-
},
9989
"install-path": "../icewind/streams"
10090
}
10191
],

apps/files_external/3rdparty/composer/installed.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
'name' => 'files_external/3rdparty',
44
'pretty_version' => 'dev-master',
55
'version' => 'dev-master',
6-
'reference' => '101c7575ae7684a572e53740c63635cd12685995',
6+
'reference' => '05e64418a77134e55824fc8c1a91125805428f3f',
77
'type' => 'library',
88
'install_path' => __DIR__ . '/../',
99
'aliases' => array(),
@@ -13,7 +13,7 @@
1313
'files_external/3rdparty' => array(
1414
'pretty_version' => 'dev-master',
1515
'version' => 'dev-master',
16-
'reference' => '101c7575ae7684a572e53740c63635cd12685995',
16+
'reference' => '05e64418a77134e55824fc8c1a91125805428f3f',
1717
'type' => 'library',
1818
'install_path' => __DIR__ . '/../',
1919
'aliases' => array(),
@@ -29,9 +29,9 @@
2929
'dev_requirement' => false,
3030
),
3131
'icewind/streams' => array(
32-
'pretty_version' => 'v0.7.7',
33-
'version' => '0.7.7.0',
34-
'reference' => '64200fd7cfcc7f550c3c695c48d8fd8bba97fecb',
32+
'pretty_version' => 'v0.7.8',
33+
'version' => '0.7.8.0',
34+
'reference' => 'cb2bd3ed41b516efb97e06e8da35a12ef58ba48b',
3535
'type' => 'library',
3636
'install_path' => __DIR__ . '/../icewind/streams',
3737
'aliases' => array(),

apps/files_external/3rdparty/icewind/streams/src/CountWrapper.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ protected function open() {
6060
return true;
6161
}
6262

63+
public function stream_seek($offset, $whence = SEEK_SET) {
64+
if ($whence === SEEK_SET) {
65+
$this->readCount = $offset;
66+
$this->writeCount = $offset;
67+
} else if ($whence === SEEK_CUR) {
68+
$this->readCount += $offset;
69+
$this->writeCount += $offset;
70+
}
71+
return parent::stream_seek($offset, $whence);
72+
}
73+
6374
public function dir_opendir($path, $options) {
6475
return $this->open();
6576
}

lib/private/Files/ObjectStore/IObjectStoreMetaData.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,13 @@ public function getObjectMetaData(string $urn): array;
3333
* @since 32.0.0
3434
*/
3535
public function listObjects(string $prefix = ''): \Iterator;
36+
37+
/**
38+
* @param string $urn the unified resource name used to identify the object
39+
* @param resource $stream stream with the data to write
40+
* @param ObjectMetaData $metaData the metadata to set for the object
41+
* @throws \Exception when something goes wrong, message will be logged
42+
* @since 32.0.0
43+
*/
44+
public function writeObjectWithMetaData(string $urn, $stream, array $metaData): void;
3645
}

lib/private/Files/ObjectStore/ObjectStoreStorage.php

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,12 @@ public function writeStream(string $path, $stream, ?int $size = null): int {
479479

480480
$mimetypeDetector = \OC::$server->getMimeTypeDetector();
481481
$mimetype = $mimetypeDetector->detectPath($path);
482+
$metadata = [
483+
'mimetype' => $mimetype,
484+
];
485+
if ($size) {
486+
$metadata['size'] = $size;
487+
}
482488

483489
$stat['mimetype'] = $mimetype;
484490
$stat['etag'] = $this->getETag($path);
@@ -500,24 +506,27 @@ public function writeStream(string $path, $stream, ?int $size = null): int {
500506
$urn = $this->getURN($fileId);
501507
try {
502508
//upload to object storage
503-
if ($size === null) {
504-
$countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, &$size) {
509+
510+
$totalWritten = 0;
511+
$countStream = CountWrapper::wrap($stream, function ($writtenSize) use ($fileId, $size, $exists, &$totalWritten) {
512+
if (is_null($size) && !$exists) {
505513
$this->getCache()->update($fileId, [
506514
'size' => $writtenSize,
507515
]);
508-
$size = $writtenSize;
509-
});
510-
$this->objectStore->writeObject($urn, $countStream, $mimetype);
511-
if (is_resource($countStream)) {
512-
fclose($countStream);
513516
}
514-
$stat['size'] = $size;
517+
$totalWritten = $writtenSize;
518+
});
519+
520+
if ($this->objectStore instanceof IObjectStoreMetaData) {
521+
$this->objectStore->writeObjectWithMetaData($urn, $countStream, $metadata);
515522
} else {
516-
$this->objectStore->writeObject($urn, $stream, $mimetype);
517-
if (is_resource($stream)) {
518-
fclose($stream);
519-
}
523+
$this->objectStore->writeObject($urn, $countStream, $metadata['mimetype']);
524+
}
525+
if (is_resource($countStream)) {
526+
fclose($countStream);
520527
}
528+
529+
$stat['size'] = $totalWritten;
521530
} catch (\Exception $ex) {
522531
if (!$exists) {
523532
/*
@@ -541,7 +550,7 @@ public function writeStream(string $path, $stream, ?int $size = null): int {
541550
]
542551
);
543552
}
544-
throw $ex; // make this bubble up
553+
throw new GenericFileException('Error while writing stream to object store', 0, $ex);
545554
}
546555

547556
if ($exists) {
@@ -557,7 +566,7 @@ public function writeStream(string $path, $stream, ?int $size = null): int {
557566
}
558567
}
559568

560-
return $size;
569+
return $totalWritten;
561570
}
562571

563572
public function getObjectStore(): IObjectStore {

0 commit comments

Comments
 (0)