Repository: owncloud/ocis
Pull request #8975 (2024-04-26 07:05:49)

build(deps): bump go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp from 0.50.0 to 0.51.0
Bumps [go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp](https://github.com/open-telemetry/opentelemetry-go-contrib) from 0.50.0 to 0.51.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/open-telemetry/opentelemetry-go-contrib/releases">go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp's releases</a>.</em></p>
<blockquote>
<h2>Release v1.26.0/v0.51.0/v0.20.0/v0.6.0/v0.1.0</h2>
<h3>Added</h3>
<ul>
<li><code>NewSDK</code> in <code>go.opentelemetry.io/contrib/config</code> now returns a configured SDK with a valid <code>MeterProvider</code>. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/4804">#4804</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Change the scope name for the prometheus bridge to <code>go.opentelemetry.io/contrib/bridges/prometheus</code> to match the package. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5396">#5396</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Fix bug where an empty exemplar was added to counters in <code>go.opentelemetry.io/contrib/bridges/prometheus</code>. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5395">#5395</a>)</li>
<li>Fix bug where the last histogram bucket was missing in <code>go.opentelemetry.io/contrib/bridges/prometheus</code>. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5395">#5395</a>)</li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/open-telemetry/opentelemetry-go-contrib/compare/v1.25.0...v1.26.0">https://github.com/open-telemetry/opentelemetry-go-contrib/compare/v1.25.0...v1.26.0</a></p>
<h2>Release v1.25.0/v0.50.0/v0.19.0/v0.5.0/v0.0.1</h2>
<h3>Added</h3>
<ul>
<li>Implemented setting the <code>cloud.resource_id</code> resource attribute in <code>go.opentelemetry.io/detectors/aws/ecs</code> based on the ECS Metadata v4 endpoint. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5091">#5091</a>)</li>
<li>The <code>go.opentelemetry.io/contrib/bridges/otelslog</code> module. This module provides an OpenTelemetry logging bridge for &quot;log/slog&quot;. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5335">#5335</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Update all dependencies to address [GO-2024-2687]. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5359">#5359</a>)</li>
</ul>
<h3>Removed</h3>
<ul>
<li>Drop support for <a href="https://go.dev/doc/go1.20">Go 1.20</a>. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5163">#5163</a>)</li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/open-telemetry/opentelemetry-go-contrib/compare/v1.24.0...v1.25.0">https://github.com/open-telemetry/opentelemetry-go-contrib/compare/v1.24.0...v1.25.0</a></p>
<h2>Release v1.24.0/v0.49.0/v0.18.0/v0.4.0</h2>
<p>This release is the last to support <a href="https://go.dev/doc/go1.20">Go 1.20</a>. The next release will require at least [Go 1.21].</p>
<h3>Added</h3>
<ul>
<li>Support [Go 1.22]. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5082">#5082</a>)</li>
<li>Add support for Summary metrics to <code>go.opentelemetry.io/contrib/bridges/prometheus</code>. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5089">#5089</a>)</li>
<li>Add support for Exponential (native) Histograms in <code>go.opentelemetry.io/contrib/bridges/prometheus</code>. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5093">#5093</a>)</li>
</ul>
<h3>Removed</h3>
<ul>
<li>The deprecated <code>RequestCount</code> constant in <code>go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp</code> is removed. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/4894">#4894</a>)</li>
<li>The deprecated <code>RequestContentLength</code> constant in <code>go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp</code> is removed. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/4894">#4894</a>)</li>
<li>The deprecated <code>ResponseContentLength</code> constant in <code>go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp</code> is removed. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/4894">#4894</a>)</li>
<li>The deprecated <code>ServerLatency</code> constant in <code>go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp</code> is removed. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/4894">#4894</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md">go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp's changelog</a>.</em></p>
<blockquote>
<h2>[1.26.0/0.51.0/0.20.0/0.6.0/0.1.0] - 2024-04-24</h2>
<h3>Added</h3>
<ul>
<li><code>NewSDK</code> in <code>go.opentelemetry.io/contrib/config</code> now returns a configured SDK with a valid <code>MeterProvider</code>. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/4804">#4804</a>)</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Change the scope name for the prometheus bridge to <code>go.opentelemetry.io/contrib/bridges/prometheus</code> to match the package. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5396">#5396</a>)</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Fix bug where an empty exemplar was added to counters in <code>go.opentelemetry.io/contrib/bridges/prometheus</code>. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5395">#5395</a>)</li>
<li>Fix bug where the last histogram bucket was missing in <code>go.opentelemetry.io/contrib/bridges/prometheus</code>. (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5395">#5395</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/8c7c4deeeb9b4cc91672f44f74745b52e3eba1c5"><code>8c7c4de</code></a> Release v1.26.0/v0.51.0/v0.20.0/v0.6.0/v0.1.0 (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5426">#5426</a>)</li>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/fed6e67d2f7b30a27a9061102d1242945afd1751"><code>fed6e67</code></a> [chore] dependabot updates Sun Apr 21 19:39:24 UTC 2024 (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5419">#5419</a>)</li>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/30ed923222392fd870a9eae264ddf7b0e301e544"><code>30ed923</code></a> HTTP Semconv migration Part1 Server - v1.20.0 support (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5333">#5333</a>)</li>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/0ebeecfb87aaa2efa3adc07624d7f249f9761d33"><code>0ebeecf</code></a> change the scope name for the prometheus bridge to match the package (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5396">#5396</a>)</li>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/e90376ce1434e152eaaa624f94c14e6697dbb677"><code>e90376c</code></a> Fix bug where an empty exemplar was added to counters (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5395">#5395</a>)</li>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/2faced475b326065fbe9253f0f6395a78c874c62"><code>2faced4</code></a> dependabot updates Sun Apr 14 19:43:32 UTC 2024 (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5394">#5394</a>)</li>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/d8b068eff0de0c187eb9fb55fd40bee48170f7d2"><code>d8b068e</code></a> build(deps): bump codecov/codecov-action from 4.2.0 to 4.3.0 (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5393">#5393</a>)</li>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/07d806815f63799717a31a53e546e2731af09992"><code>07d8068</code></a> config: NewSDK can return valid MeterProvider (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/4804">#4804</a>)</li>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/7a9e861fbac7e49c9945a90249dd3e2fce0a0265"><code>7a9e861</code></a> Add benchmarks for the prometheus bridge (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5364">#5364</a>)</li>
<li><a href="https://github.com/open-telemetry/opentelemetry-go-contrib/commit/b343370e70b6e5a4881b7cd9915af95bd58d121f"><code>b343370</code></a> build(deps): bump codecov/codecov-action from 4.1.1 to 4.2.0 (<a href="https://redirect.github.com/open-telemetry/opentelemetry-go-contrib/issues/5369">#5369</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.50.0...zpages/v0.51.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp&package-manager=go_modules&previous-version=0.50.0&new-version=0.51.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fc946352d5b..e56e74ca2ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -70,6 +70,7 @@ The following sections list the changes for unreleased.
 * Bugfix - Update the admin user role assignment to enforce the config: [#8897](https://github.com/owncloud/ocis/pull/8897)
 * Bugfix - Fix affected users on sses: [#8928](https://github.com/owncloud/ocis/pull/8928)
 * Bugfix - Fix well-known rewrite endpoint: [#8946](https://github.com/owncloud/ocis/pull/8946)
+* Bugfix - Crash when processing crafted TIFF files: [#8981](https://github.com/owncloud/ocis/pull/8981)
 * Change - Change the default store for presigned keys to nats-js-kv: [#8419](https://github.com/owncloud/ocis/pull/8419)
 * Change - Disable resharing by default for deprecation: [#8653](https://github.com/owncloud/ocis/pull/8653)
 * Enhancement - Introduce staticroutes package & remove well-known OIDC middleware: [#6095](https://github.com/owncloud/ocis/issues/6095)
@@ -290,6 +291,13 @@ The following sections list the changes for unreleased.
    https://github.com/owncloud/ocis/issues/8703
    https://github.com/owncloud/ocis/pull/8946
 
+* Bugfix - Crash when processing crafted TIFF files: [#8981](https://github.com/owncloud/ocis/pull/8981)
+
+   Fix for a vulnerability with low severity in disintegration/imaging.
+
+   https://github.com/owncloud/ocis/pull/8981
+   https://github.com/advisories/GHSA-q7pp-wcgr-pffx
+
 * Change - Change the default store for presigned keys to nats-js-kv: [#8419](https://github.com/owncloud/ocis/pull/8419)
 
    We wrapped the store service in a micro store implementation and changed the
diff --git a/changelog/unreleased/CVE-2023-36308.md b/changelog/unreleased/CVE-2023-36308.md
new file mode 100644
index 00000000000..a8abb032121
--- /dev/null
+++ b/changelog/unreleased/CVE-2023-36308.md
@@ -0,0 +1,7 @@
+Bugfix: Crash when processing crafted TIFF files
+
+Fix for a vulnerability with low severity in disintegration/imaging.
+
+https://github.com/advisories/GHSA-q7pp-wcgr-pffx
+https://github.com/owncloud/ocis/pull/8981
+
diff --git a/deployments/examples/ocis_wopi/.env b/deployments/examples/ocis_wopi/.env
index 2fa5355238d..d25cea9b688 100644
--- a/deployments/examples/ocis_wopi/.env
+++ b/deployments/examples/ocis_wopi/.env
@@ -22,6 +22,8 @@ ADMIN_PASSWORD=
 # The demo users should not be created on a production instance
 # because their passwords are public. Defaults to "false".
 DEMO_USERS=
+# Log level for OCIS_DOCKER_TAG
+OCIS_LOG_LEVEL=
 
 ### Wopi server settings ###
 # cs3org wopi server version. Defaults to "v8.3.3"
diff --git a/deployments/examples/ocis_wopi/docker-compose.yml b/deployments/examples/ocis_wopi/docker-compose.yml
index 02bf4a0a82f..a6c6012fefb 100644
--- a/deployments/examples/ocis_wopi/docker-compose.yml
+++ b/deployments/examples/ocis_wopi/docker-compose.yml
@@ -116,6 +116,7 @@ services:
       - /entrypoint-override.sh
     command: app-provider server
     environment:
+      OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-info}
       # use the internal service name of the gateway
       REVA_GATEWAY: ${REVA_GATEWAY:-com.owncloud.api.gateway}
       APP_PROVIDER_GRPC_ADDR: 0.0.0.0:9164
@@ -151,6 +152,7 @@ services:
       - /entrypoint-override.sh
     #command: app-provider server
     environment:
+      OCIS_LOG_LEVEL: ${OCIS_LOG_LEVEL:-info}
       # use the internal service name of the gateway
       REVA_GATEWAY: ${REVA_GATEWAY:-com.owncloud.api.gateway}
       APP_PROVIDER_GRPC_ADDR: 0.0.0.0:9164
diff --git a/go.mod b/go.mod
index b7b5372cae5..dce152934c5 100644
--- a/go.mod
+++ b/go.mod
@@ -15,9 +15,8 @@ require (
 	github.com/cenkalti/backoff v2.2.1+incompatible
 	github.com/coreos/go-oidc/v3 v3.10.0
 	github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781
-	github.com/cs3org/reva/v2 v2.19.2-0.20240422150349-51ab7655f858
+	github.com/cs3org/reva/v2 v2.19.2-0.20240426071117-7ed0671f9e0b
 	github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
-	github.com/disintegration/imaging v1.6.2
 	github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
 	github.com/egirna/icap-client v0.1.1
 	github.com/gabriel-vasile/mimetype v1.4.3
@@ -56,6 +55,7 @@ require (
 	github.com/jellydator/ttlcache/v3 v3.2.0
 	github.com/jinzhu/now v1.1.5
 	github.com/justinas/alice v1.2.0
+	github.com/kovidgoyal/imaging v1.6.3
 	github.com/leonelquinteros/gotext v1.6.0
 	github.com/libregraph/idm v0.5.0
 	github.com/libregraph/lico v0.61.3-0.20240322112242-72cf9221d3a7
@@ -92,7 +92,7 @@ require (
 	github.com/xhit/go-simple-mail/v2 v2.16.0
 	go-micro.dev/v4 v4.10.2
 	go.etcd.io/bbolt v1.3.9
-	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0
+	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0
 	go.opentelemetry.io/contrib/zpages v0.49.0
 	go.opentelemetry.io/otel v1.26.0
 	go.opentelemetry.io/otel/exporters/jaeger v1.17.0
@@ -104,7 +104,7 @@ require (
 	golang.org/x/image v0.15.0
 	golang.org/x/net v0.24.0
 	golang.org/x/oauth2 v0.19.0
-	golang.org/x/sync v0.6.0
+	golang.org/x/sync v0.7.0
 	golang.org/x/term v0.19.0
 	golang.org/x/text v0.14.0
 	google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de
diff --git a/go.sum b/go.sum
index 355d58d8ee9..ba008989ffc 100644
--- a/go.sum
+++ b/go.sum
@@ -1026,8 +1026,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c=
 github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME=
 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY=
 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
-github.com/cs3org/reva/v2 v2.19.2-0.20240422150349-51ab7655f858 h1:cohKwOI/6UXXYhrjrZMYxw5GlM8wFS5445TZr/jmSzs=
-github.com/cs3org/reva/v2 v2.19.2-0.20240422150349-51ab7655f858/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E=
+github.com/cs3org/reva/v2 v2.19.2-0.20240426071117-7ed0671f9e0b h1:lYNsGv/E06cD+p5RLmxBVySV17/OVRBiOhL50FEUrGs=
+github.com/cs3org/reva/v2 v2.19.2-0.20240426071117-7ed0671f9e0b/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E=
 github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
 github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
 github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
@@ -1056,8 +1056,6 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8
 github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25 h1:simG0vMYFvNriGhaaat7QVVkaVkXzvqcohaBoLZl9Hg=
 github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25/go.mod h1:Z3Lomva4pyMWYezjMAU5QWRh0p1VvO4199OHlFnyKkM=
 github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
-github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
-github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
 github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
 github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
 github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
@@ -1613,6 +1611,8 @@ github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b/go.mod h1:o03bZfuBwAXH
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kovidgoyal/imaging v1.6.3 h1:iNPpv7ygiaB/NOztc6APMT7yr9UwBS+rOZwIbAdtyY8=
+github.com/kovidgoyal/imaging v1.6.3/go.mod h1:sHvcLOOVhJuto2IoNdPLEqnAUoL5ZfHEF0PpNH+882g=
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -2104,8 +2104,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 h1:P+/g8GpuJGYbOp2tAdKrIPUX9JO02q8Q0YNlHolpibA=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0/go.mod h1:tIKj3DbO8N9Y2xo52og3irLsPI4GW02DSMtrVgNMgxg=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
 go.opentelemetry.io/contrib/zpages v0.49.0 h1:Wk217PkNBxcKWnIQpwtbZZE286K4ZY9uajnM5woSeLU=
 go.opentelemetry.io/contrib/zpages v0.49.0/go.mod h1:6alLi5mmkZWbAtZMRPd1ffIgkTcsU9OTHQF2NbSOhrQ=
 go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
@@ -2200,7 +2200,6 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -2377,8 +2376,8 @@ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
diff --git a/services/antivirus/pkg/service/service.go b/services/antivirus/pkg/service/service.go
index 21ab9a77454..a1d41c651c9 100644
--- a/services/antivirus/pkg/service/service.go
+++ b/services/antivirus/pkg/service/service.go
@@ -146,7 +146,7 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
 	}
 
 	if av.c.DebugScanOutcome != "" {
-		av.l.Warn().Str("antivir, clamav", ">>>>>>> ANTIVIRUS_DEBUG_SCAN_OUTCOME IS SET NO ACTUAL VIRUS SCAN IS PERFORMED!")
+		av.l.Warn().Str("antivir, clamav", ">>>>>>> ANTIVIRUS_DEBUG_SCAN_OUTCOME IS SET NO ACTUAL VIRUS SCAN IS PERFORMED!").Send()
 		if err := events.Publish(ctx, s, events.PostprocessingStepFinished{
 			FinishedStep:  events.PPStepAntivirus,
 			Outcome:       events.PostprocessingOutcome(av.c.DebugScanOutcome),
@@ -158,7 +158,6 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
 				Description: "DEBUG: forced outcome",
 				Scandate:    time.Now(),
 				ResourceID:  ev.ResourceID,
-				ErrorMsg:    "DEBUG: forced outcome",
 			},
 		}); err != nil {
 			av.l.Fatal().Err(err).Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Msg("cannot publish events - exiting")
diff --git a/services/clientlog/pkg/service/service.go b/services/clientlog/pkg/service/service.go
index 90cb5cdae4d..dbd9ae1cece 100644
--- a/services/clientlog/pkg/service/service.go
+++ b/services/clientlog/pkg/service/service.go
@@ -113,6 +113,10 @@ func (cl *ClientlogService) processEvent(event events.Event) {
 	default:
 		err = errors.New("unhandled event")
 	case events.UploadReady:
+		if e.Failed {
+			// we don't inform about failed uploads yet
+			return
+		}
 		fileEv("postprocessing-finished", e.FileRef)
 	case events.ItemTrashed:
 		evType = "item-trashed"
diff --git a/services/postprocessing/pkg/postprocessing/postprocessing.go b/services/postprocessing/pkg/postprocessing/postprocessing.go
index e462401a552..1a27bfd5024 100644
--- a/services/postprocessing/pkg/postprocessing/postprocessing.go
+++ b/services/postprocessing/pkg/postprocessing/postprocessing.go
@@ -22,6 +22,7 @@ type Postprocessing struct {
 	Status      Status
 	Failures    int
 	InitiatorID string
+	Finished    bool
 
 	config config.Postprocessing
 }
diff --git a/services/postprocessing/pkg/service/service.go b/services/postprocessing/pkg/service/service.go
index 2be92d6fc82..95430e61891 100644
--- a/services/postprocessing/pkg/service/service.go
+++ b/services/postprocessing/pkg/service/service.go
@@ -150,8 +150,14 @@ func (pps *PostprocessingService) processEvent(e events.Event) error {
 		next = pp.Delay()
 	case events.UploadReady:
 		if ev.Failed {
-			// the upload failed - let's keep it around for a while
-			return nil
+			// the upload failed - let's keep it around for a while - but mark it as finished
+			pp, err = pps.getPP(pps.store, ev.UploadID)
+			if err != nil {
+				pps.log.Error().Str("uploadID", ev.UploadID).Err(err).Msg("cannot get upload")
+				return fmt.Errorf("%w: cannot get upload", ErrEvent)
+			}
+			pp.Finished = true
+			return storePP(pps.store, pp)
 		}
 
 		// the storage provider thinks the upload is done - so no need to keep it any more
@@ -261,6 +267,11 @@ func (pps *PostprocessingService) resumePP(ctx context.Context, uploadID string)
 		return fmt.Errorf("cannot get upload: %w", err)
 	}
 
+	if pp.Finished {
+		// dont retry finished uploads
+		return nil
+	}
+
 	return events.Publish(ctx, pps.pub, pp.CurrentStep())
 }
 
diff --git a/services/storage-users/pkg/command/uploads.go b/services/storage-users/pkg/command/uploads.go
index e5ae4f25613..433773637c2 100644
--- a/services/storage-users/pkg/command/uploads.go
+++ b/services/storage-users/pkg/command/uploads.go
@@ -191,6 +191,7 @@ func ListUploadSessions(cfg *config.Config) *cli.Command {
 			if c.Bool("json") {
 				for _, u := range uploads {
 					ref := u.Reference()
+					sr, sd := u.ScanData()
 					s := struct {
 						ID         string         `json:"id"`
 						Space      string         `json:"space"`
@@ -201,6 +202,8 @@ func ListUploadSessions(cfg *config.Config) *cli.Command {
 						SpaceOwner *userpb.UserId `json:"spaceowner,omitempty"`
 						Expires    time.Time      `json:"expires"`
 						Processing bool           `json:"processing"`
+						ScanDate   time.Time      `json:"virus_scan_date"`
+						ScanResult string         `json:"virus_scan_result"`
 					}{
 						Space:      ref.GetResourceId().GetSpaceId(),
 						ID:         u.ID(),
@@ -211,6 +214,8 @@ func ListUploadSessions(cfg *config.Config) *cli.Command {
 						SpaceOwner: u.SpaceOwner(),
 						Expires:    u.Expires(),
 						Processing: u.IsProcessing(),
+						ScanDate:   sd,
+						ScanResult: sr,
 					}
 					j, err := json.Marshal(s)
 					if err != nil {
@@ -236,10 +241,11 @@ func ListUploadSessions(cfg *config.Config) *cli.Command {
 
 				// start a table
 				table = tw.NewWriter(os.Stdout)
-				table.SetHeader([]string{"Space", "Upload Id", "Name", "Offset", "Size", "Executant", "Owner", "Expires", "Processing"})
+				table.SetHeader([]string{"Space", "Upload Id", "Name", "Offset", "Size", "Executant", "Owner", "Expires", "Processing", "Scan Date", "Scan Result"})
 				table.SetAutoFormatHeaders(false)
 
 				for _, u := range uploads {
+					sr, sd := u.ScanData()
 					table.Append([]string{
 						u.Reference().ResourceId.GetSpaceId(),
 						u.ID(),
@@ -250,6 +256,8 @@ func ListUploadSessions(cfg *config.Config) *cli.Command {
 						u.SpaceOwner().GetOpaqueId(),
 						u.Expires().Format(time.RFC3339),
 						strconv.FormatBool(u.IsProcessing()),
+						sd.Format(time.RFC3339),
+						sr,
 					})
 
 					if c.Bool("restart") {
diff --git a/services/thumbnails/pkg/preprocessor/preprocessor.go b/services/thumbnails/pkg/preprocessor/preprocessor.go
index b8949dc953d..d8addd3a709 100644
--- a/services/thumbnails/pkg/preprocessor/preprocessor.go
+++ b/services/thumbnails/pkg/preprocessor/preprocessor.go
@@ -12,7 +12,7 @@ import (
 	"mime"
 	"strings"
 
-	"github.com/disintegration/imaging"
+	"github.com/kovidgoyal/imaging"
 	"github.com/pkg/errors"
 	"golang.org/x/image/font"
 	"golang.org/x/image/font/opentype"
diff --git a/services/thumbnails/pkg/thumbnail/generator.go b/services/thumbnails/pkg/thumbnail/generator.go
index 64aa086dff6..80796ad7ce8 100644
--- a/services/thumbnails/pkg/thumbnail/generator.go
+++ b/services/thumbnails/pkg/thumbnail/generator.go
@@ -7,7 +7,7 @@ import (
 	"image/gif"
 	"strings"
 
-	"github.com/disintegration/imaging"
+	"github.com/kovidgoyal/imaging"
 )
 
 // Generator generates a web friendly file version.
diff --git a/services/thumbnails/pkg/thumbnail/processor.go b/services/thumbnails/pkg/thumbnail/processor.go
index 3782fac4fce..59bbe3a6369 100644
--- a/services/thumbnails/pkg/thumbnail/processor.go
+++ b/services/thumbnails/pkg/thumbnail/processor.go
@@ -4,7 +4,7 @@ import (
 	"image"
 	"strings"
 
-	"github.com/disintegration/imaging"
+	"github.com/kovidgoyal/imaging"
 )
 
 // Processor processes the thumbnail by applying different transformations to it.
@@ -13,7 +13,7 @@ type Processor interface {
 	Process(img image.Image, width, height int, filter imaging.ResampleFilter) *image.NRGBA
 }
 
-// DefinableProcessor is the most simple processor, it holds a replaceable image converter function.
+// DefinableProcessor is the simplest processor, it holds a replaceable image converter function.
 type DefinableProcessor struct {
 	Slug      string
 	Converter func(img image.Image, width, height int, filter imaging.ResampleFilter) *image.NRGBA
diff --git a/services/webfinger/pkg/command/server.go b/services/webfinger/pkg/command/server.go
index cfba7bf6834..adb89f72aa3 100644
--- a/services/webfinger/pkg/command/server.go
+++ b/services/webfinger/pkg/command/server.go
@@ -44,17 +44,17 @@ func Server(cfg *config.Config) *cli.Command {
 					}
 					return context.WithCancel(cfg.Context)
 				}()
-				metrics = metrics.New(metrics.Logger(logger))
+				m = metrics.New(metrics.Logger(logger))
 			)
 
 			defer cancel()
 
-			metrics.BuildInfo.WithLabelValues(version.GetString()).Set(1)
+			m.BuildInfo.WithLabelValues(version.GetString()).Set(1)
 
 			{
 				relationProviders, err := getRelationProviders(cfg)
 				if err != nil {
-					logger.Error().Err(err).Msg("relation providier init")
+					logger.Error().Err(err).Msg("relation provider init")
 					return err
 				}
 
@@ -67,7 +67,7 @@ func Server(cfg *config.Config) *cli.Command {
 					logger.Error().Err(err).Msg("handler init")
 					return err
 				}
-				svc = service.NewInstrument(svc, metrics)
+				svc = service.NewInstrument(svc, m)
 				svc = service.NewLogging(svc, logger) // this logs service specific data
 				svc = service.NewTracing(svc, traceProvider)
 
diff --git a/services/webfinger/pkg/config/parser/parse.go b/services/webfinger/pkg/config/parser/parse.go
index 55d657e93bd..014f95a27d5 100644
--- a/services/webfinger/pkg/config/parser/parse.go
+++ b/services/webfinger/pkg/config/parser/parse.go
@@ -32,6 +32,6 @@ func ParseConfig(cfg *config.Config) error {
 	return Validate(cfg)
 }
 
-func Validate(cfg *config.Config) error {
+func Validate(_ *config.Config) error {
 	return nil
 }
diff --git a/services/webfinger/pkg/relations/openid_discovery.go b/services/webfinger/pkg/relations/openid_discovery.go
index 43bae7f9b95..53cb315b609 100644
--- a/services/webfinger/pkg/relations/openid_discovery.go
+++ b/services/webfinger/pkg/relations/openid_discovery.go
@@ -22,7 +22,7 @@ func OpenIDDiscovery(href string) service.RelationProvider {
 	}
 }
 
-func (l *openIDDiscovery) Add(ctx context.Context, jrd *webfinger.JSONResourceDescriptor) {
+func (l *openIDDiscovery) Add(_ context.Context, jrd *webfinger.JSONResourceDescriptor) {
 	if jrd == nil {
 		jrd = &webfinger.JSONResourceDescriptor{}
 	}
diff --git a/services/webfinger/pkg/server/debug/server.go b/services/webfinger/pkg/server/debug/server.go
index 27719954f10..2701befb13f 100644
--- a/services/webfinger/pkg/server/debug/server.go
+++ b/services/webfinger/pkg/server/debug/server.go
@@ -31,7 +31,7 @@ func Server(opts ...Option) (*http.Server, error) {
 }
 
 // health implements the health check.
-func health(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
+func health(_ *config.Config) func(http.ResponseWriter, *http.Request) {
 	return func(w http.ResponseWriter, r *http.Request) {
 		w.Header().Set("Content-Type", "text/plain")
 		w.WriteHeader(http.StatusOK)
@@ -47,7 +47,7 @@ func health(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
 }
 
 // ready implements the ready check.
-func ready(cfg *config.Config) func(http.ResponseWriter, *http.Request) {
+func ready(_ *config.Config) func(http.ResponseWriter, *http.Request) {
 	return func(w http.ResponseWriter, r *http.Request) {
 		w.Header().Set("Content-Type", "text/plain")
 		w.WriteHeader(http.StatusOK)
diff --git a/services/webfinger/pkg/server/http/option.go b/services/webfinger/pkg/server/http/option.go
index df5d6635b2d..8846a0788dd 100644
--- a/services/webfinger/pkg/server/http/option.go
+++ b/services/webfinger/pkg/server/http/option.go
@@ -2,6 +2,7 @@ package http
 
 import (
 	"context"
+	"go.opentelemetry.io/otel/trace/noop"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	"github.com/owncloud/ocis/v2/services/webfinger/pkg/config"
@@ -36,13 +37,6 @@ func newOptions(opts ...Option) Options {
 	return opt
 }
 
-// Name provides a name for the service.
-func Name(val string) Option {
-	return func(o *Options) {
-		o.Name = val
-	}
-}
-
 // Logger provides a function to set the logger option.
 func Logger(val log.Logger) Option {
 	return func(o *Options) {
@@ -64,20 +58,6 @@ func Config(val *config.Config) Option {
 	}
 }
 
-// Flags provides a function to set the flags option.
-func Flags(val []cli.Flag) Option {
-	return func(o *Options) {
-		o.Flags = append(o.Flags, val...)
-	}
-}
-
-// Namespace provides a function to set the namespace option.
-func Namespace(val string) Option {
-	return func(o *Options) {
-		o.Namespace = val
-	}
-}
-
 // Service provides a function to set the service option.
 func Service(val svc.Service) Option {
 	return func(o *Options) {
@@ -91,7 +71,7 @@ func TraceProvider(traceProvider trace.TracerProvider) Option {
 		if traceProvider != nil {
 			o.TraceProvider = traceProvider
 		} else {
-			o.TraceProvider = trace.NewNoopTracerProvider()
+			o.TraceProvider = noop.NewTracerProvider()
 		}
 	}
 }
diff --git a/services/webfinger/pkg/server/http/server.go b/services/webfinger/pkg/server/http/server.go
index 45e49f76fdf..2f5553c184e 100644
--- a/services/webfinger/pkg/server/http/server.go
+++ b/services/webfinger/pkg/server/http/server.go
@@ -26,7 +26,7 @@ func Server(opts ...Option) (ohttp.Service, error) {
 	options := newOptions(opts...)
 	service := options.Service
 
-	svc, err := ohttp.NewService(
+	newService, err := ohttp.NewService(
 		ohttp.TLSConfig(options.Config.HTTP.TLS),
 		ohttp.Logger(options.Logger),
 		ohttp.Namespace(options.Config.HTTP.Namespace),
@@ -98,13 +98,13 @@ func Server(opts ...Option) (ohttp.Service, error) {
 		r.Get("/.well-known/webfinger", WebfingerHandler(service))
 	})
 
-	err = micro.RegisterHandler(svc.Server(), mux)
+	err = micro.RegisterHandler(newService.Server(), mux)
 	if err != nil {
 		options.Logger.Fatal().Err(err).Msg("failed to register the handler")
 	}
 
-	svc.Init()
-	return svc, nil
+	newService.Init()
+	return newService, nil
 }
 
 func WebfingerHandler(service svc.Service) func(w http.ResponseWriter, r *http.Request) {
diff --git a/services/webfinger/pkg/service/v0/service.go b/services/webfinger/pkg/service/v0/service.go
index 238fbbf64e8..98364fe84f2 100644
--- a/services/webfinger/pkg/service/v0/service.go
+++ b/services/webfinger/pkg/service/v0/service.go
@@ -9,11 +9,6 @@ import (
 	"github.com/owncloud/ocis/v2/services/webfinger/pkg/webfinger"
 )
 
-const (
-	OwnCloudInstanceRel = "http://webfinger.owncloud/rel/server-instance"
-	OpenIDConnectRel    = "http://openid.net/specs/connect/1.0/issuer"
-)
-
 // Service defines the extension handlers.
 type Service interface {
 	// Webfinger is the endpoint for retrieving various href relations.
@@ -78,7 +73,7 @@ type svc struct {
 }
 
 // TODO implement different implementations:
-// static one returning the href or a configureable domain
+// static one returning the href or a configurable domain
 // regex one returning different instances based on the regex that matches
 // claim one that reads a claim and then fetches the instance?
 // that is actually two interfaces / steps:
diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go
index dd0e8604c86..919845efb6b 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go
@@ -20,6 +20,7 @@ package gateway
 
 import (
 	"context"
+	"slices"
 
 	rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
 	collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
@@ -158,6 +159,9 @@ func (s *svc) updateShare(ctx context.Context, req *collaboration.UpdateShareReq
 }
 
 func (s *svc) updateSpaceShare(ctx context.Context, req *collaboration.UpdateShareRequest) (*collaboration.UpdateShareResponse, error) {
+	if req.GetShare().GetGrantee() == nil {
+		return &collaboration.UpdateShareResponse{Status: status.NewInvalid(ctx, "updating requires a received grantee object")}, nil
+	}
 	// If the share is a denial we call  denyGrant instead.
 	var st *rpc.Status
 	var err error
@@ -169,32 +173,47 @@ func (s *svc) updateSpaceShare(ctx context.Context, req *collaboration.UpdateSha
 	}
 	utils.AppendPlainToOpaque(opaque, "spacetype", utils.ReadPlainFromOpaque(req.Opaque, "spacetype"))
 
-	creator := ctxpkg.ContextMustGetUser(ctx)
-	grant := &provider.Grant{
-		Grantee:     req.GetShare().GetGrantee(),
-		Permissions: req.GetShare().GetPermissions().GetPermissions(),
-		Expiration:  req.GetShare().GetExpiration(),
-		Creator:     creator.GetId(),
-	}
 	if grants.PermissionsEqual(req.Share.GetPermissions().GetPermissions(), &provider.ResourcePermissions{}) {
 		st, err = s.denyGrant(ctx, req.GetShare().GetResourceId(), req.GetShare().GetGrantee(), opaque)
 		if err != nil {
 			return nil, errors.Wrap(err, "gateway: error denying grant in storage")
 		}
 	} else {
-		if !grant.Permissions.RemoveGrant {
+		listGrantRes, err := s.listGrants(ctx, req.GetShare().GetResourceId())
+		if err != nil {
+			return nil, errors.Wrap(err, "gateway: error getting grant to remove from storage")
+		}
+		existsGrant := s.getGranteeGrant(listGrantRes.GetGrants(), req.GetShare().GetGrantee())
+
+		if !slices.Contains(req.GetUpdateMask().GetPaths(), "permissions") {
+			req.Share.Permissions = &collaboration.SharePermissions{Permissions: existsGrant.GetPermissions()}
+		}
+
+		if !slices.Contains(req.GetUpdateMask().GetPaths(), "expiration") {
+			req.Share.Expiration = existsGrant.GetExpiration()
+		}
+
+		grant := &provider.Grant{
+			Grantee:     req.GetShare().GetGrantee(),
+			Permissions: req.GetShare().GetPermissions().GetPermissions(),
+			Expiration:  req.GetShare().GetExpiration(),
+			Creator:     ctxpkg.ContextMustGetUser(ctx).GetId(),
+		}
+
+		if grant.GetPermissions() == nil {
+			return &collaboration.UpdateShareResponse{Status: status.NewInvalid(ctx, "updating requires a received permission object")}, nil
+		}
+
+		if !grant.GetPermissions().GetRemoveGrant() {
 			// this request might remove Manager Permissions so we need to
 			// check if there is at least one manager remaining of the
 			// resource.
-			listGrantRes, err := s.listGrants(ctx, req.GetShare().GetResourceId())
-			if err != nil {
-				return nil, errors.Wrap(err, "gateway: error getting grant to remove from storage")
-			}
 			if !isSpaceManagerRemaining(listGrantRes.GetGrants(), grant.GetGrantee()) {
 				return &collaboration.UpdateShareResponse{
 					Status: status.NewPermissionDenied(ctx, errtypes.PermissionDenied(""), "can't remove the last manager"),
 				}, nil
 			}
+
 		}
 		st, err = s.updateGrant(ctx, req.GetShare().GetResourceId(), grant, opaque)
 		if err != nil {
@@ -523,6 +542,15 @@ func (s *svc) listGrants(ctx context.Context, id *provider.ResourceId) (*provide
 	return grantRes, nil
 }
 
+func (s *svc) getGranteeGrant(grants []*provider.Grant, grantee *provider.Grantee) *provider.Grant {
+	for _, g := range grants {
+		if isEqualGrantee(g.Grantee, grantee) {
+			return g
+		}
+	}
+	return nil
+}
+
 func (s *svc) addShare(ctx context.Context, req *collaboration.CreateShareRequest) (*collaboration.CreateShareResponse, error) {
 	c, err := pool.GetUserShareProviderClient(s.c.UserShareProviderEndpoint)
 	if err != nil {
diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go
index f3def1ca593..35ccf7a65b8 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/spaces.go
@@ -41,6 +41,7 @@ import (
 	"github.com/cs3org/reva/v2/pkg/storagespace"
 	"github.com/cs3org/reva/v2/pkg/utils"
 	"github.com/pkg/errors"
+	"google.golang.org/protobuf/types/known/fieldmaskpb"
 )
 
 func (h *Handler) getGrantee(ctx context.Context, name string) (provider.Grantee, error) {
@@ -108,8 +109,10 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p
 	// The viewer role doesn't have the ListGrants permission so we set it here.
 	permissions.ListGrants = true
 
+	fieldmask := []string{}
 	expireDate := r.PostFormValue("expireDate")
 	var expirationTs *types.Timestamp
+	fieldmask = append(fieldmask, "expiration")
 	if expireDate != "" {
 		expiration, err := time.Parse(_iso8601, expireDate)
 		if err != nil {
@@ -125,6 +128,7 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p
 			Seconds: uint64(expiration.UnixNano() / int64(time.Second)),
 			Nanos:   uint32(expiration.UnixNano() % int64(time.Second)),
 		}
+		fieldmask = append(fieldmask, "expiration")
 	}
 
 	ref := provider.Reference{ResourceId: info.GetId()}
@@ -154,6 +158,9 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p
 	// we have to send the update request to the gateway to give it a chance to invalidate its cache
 	// TODO the gateway no longer should cache stuff because invalidation is to expensive. The decomposedfs already has a better cache.
 	if granteeExists(lgRes.Grants, grantee) {
+		if permissions != nil {
+			fieldmask = append(fieldmask, "permissions")
+		}
 		updateShareReq := &collaborationv1beta1.UpdateShareRequest{
 			// TODO: change CS3 APIs
 			Opaque: &types.Opaque{
@@ -169,6 +176,9 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p
 				Grantee:    &grantee,
 				Expiration: expirationTs,
 			},
+			UpdateMask: &fieldmaskpb.FieldMask{
+				Paths: fieldmask,
+			},
 		}
 		updateShareReq.Opaque = utils.AppendPlainToOpaque(updateShareReq.Opaque, "spacetype", info.GetSpace().GetSpaceType())
 		updateShareRes, err := client.UpdateShare(ctx, updateShareReq)
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/uploads.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/uploads.go
index 87d26115bf2..f6ef9ad2d72 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/uploads.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/uploads.go
@@ -76,6 +76,9 @@ type UploadSession interface {
 
 	// Purge allows completely removing an upload. Should emit a PostprocessingFinished event with a Delete outcome
 	Purge(ctx context.Context) error
+
+	// ScanData returns the scan data for the UploadSession
+	ScanData() (string, time.Time)
 }
 
 // UploadSessionFilter can be used to filter upload sessions
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go
index 9af86b4c437..19e5f063012 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go
@@ -496,6 +496,11 @@ func (fs *Decomposedfs) Postprocessing(ch <-chan events.Event) {
 					continue
 				}
 				sublog = log.With().Str("spaceid", session.SpaceID()).Str("nodeid", session.NodeID()).Logger()
+
+				session.SetScanData(res.Description, res.Scandate)
+				if err := session.Persist(ctx); err != nil {
+					sublog.Error().Err(err).Msg("Failed to persist scan results")
+				}
 			}
 
 			if err := n.SetScanData(ctx, res.Description, res.Scandate); err != nil {
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/session.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/session.go
index b7ba2b60040..c008c274dd7 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/session.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/session.go
@@ -298,7 +298,8 @@ func (s *OcisSession) MTime() time.Time {
 
 // IsProcessing returns true if all bytes have been received. The session then has entered postprocessing state.
 func (s *OcisSession) IsProcessing() bool {
-	return s.info.Size == s.info.Offset
+	// We might need a more sophisticated way to determine processing status soon
+	return s.info.Size == s.info.Offset && s.info.MetaData["scanResult"] == ""
 }
 
 // binPath returns the path to the file storing the binary data.
@@ -311,6 +312,22 @@ func (s *OcisSession) InitiatorID() string {
 	return s.info.MetaData["initiatorid"]
 }
 
+// SetScanData sets virus scan data to the upload session
+func (s *OcisSession) SetScanData(result string, date time.Time) {
+	s.info.MetaData["scanResult"] = result
+	s.info.MetaData["scanDate"] = date.Format(time.RFC3339)
+}
+
+// ScanData returns the virus scan data
+func (s *OcisSession) ScanData() (string, time.Time) {
+	date := s.info.MetaData["scanDate"]
+	if date == "" {
+		return "", time.Time{}
+	}
+	d, _ := time.Parse(time.RFC3339, date)
+	return s.info.MetaData["scanResult"], d
+}
+
 // sessionPath returns the path to the .info file storing the file's info.
 func sessionPath(root, id string) string {
 	return filepath.Join(root, "uploads", id+".info")
diff --git a/vendor/github.com/disintegration/imaging/.travis.yml b/vendor/github.com/disintegration/imaging/.travis.yml
deleted file mode 100644
index 7ae5e4b25a5..00000000000
--- a/vendor/github.com/disintegration/imaging/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-language: go
-go:
-  - "1.10.x"
-  - "1.11.x"
-  - "1.12.x"
-
-before_install:
-  - go get github.com/mattn/goveralls
-
-script:
-  - go test -v -race -cover
-  - $GOPATH/bin/goveralls -service=travis-ci
diff --git a/vendor/github.com/kovidgoyal/imaging/.gitignore b/vendor/github.com/kovidgoyal/imaging/.gitignore
new file mode 100644
index 00000000000..cde012322cd
--- /dev/null
+++ b/vendor/github.com/kovidgoyal/imaging/.gitignore
@@ -0,0 +1,2 @@
+
+dist/
diff --git a/vendor/github.com/kovidgoyal/imaging/.goreleaser.yaml b/vendor/github.com/kovidgoyal/imaging/.goreleaser.yaml
new file mode 100644
index 00000000000..25c4966c466
--- /dev/null
+++ b/vendor/github.com/kovidgoyal/imaging/.goreleaser.yaml
@@ -0,0 +1,41 @@
+# This is an example .goreleaser.yml file with some sensible defaults.
+# Make sure to check the documentation at https://goreleaser.com
+
+# The lines below are called `modelines`. See `:help modeline`
+# Feel free to remove those if you don't want/need to use them.
+# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
+# vim: set ts=2 sw=2 tw=0 fo=cnqoj
+
+version: 1
+
+before:
+  hooks:
+    # You may remove this if you don't use go modules.
+    - go mod tidy
+    # you may remove this if you don't need go generate
+    - go generate ./...
+
+builds:
+  - skip: true
+
+archives:
+  - format: tar.gz
+    # this name template makes the OS and Arch compatible with the results of `uname`.
+    name_template: >-
+      {{ .ProjectName }}_
+      {{- title .Os }}_
+      {{- if eq .Arch "amd64" }}x86_64
+      {{- else if eq .Arch "386" }}i386
+      {{- else }}{{ .Arch }}{{ end }}
+      {{- if .Arm }}v{{ .Arm }}{{ end }}
+    # use zip for windows archives
+    format_overrides:
+      - goos: windows
+        format: zip
+
+changelog:
+  sort: asc
+  filters:
+    exclude:
+      - "^docs:"
+      - "^test:"
diff --git a/vendor/github.com/disintegration/imaging/LICENSE b/vendor/github.com/kovidgoyal/imaging/LICENSE
similarity index 100%
rename from vendor/github.com/disintegration/imaging/LICENSE
rename to vendor/github.com/kovidgoyal/imaging/LICENSE
diff --git a/vendor/github.com/disintegration/imaging/README.md b/vendor/github.com/kovidgoyal/imaging/README.md
similarity index 88%
rename from vendor/github.com/disintegration/imaging/README.md
rename to vendor/github.com/kovidgoyal/imaging/README.md
index a1fd764d2c7..7ca37e40907 100644
--- a/vendor/github.com/disintegration/imaging/README.md
+++ b/vendor/github.com/kovidgoyal/imaging/README.md
@@ -1,226 +1,231 @@
-# Imaging
-
-[![GoDoc](https://godoc.org/github.com/disintegration/imaging?status.svg)](https://godoc.org/github.com/disintegration/imaging)
-[![Build Status](https://travis-ci.org/disintegration/imaging.svg?branch=master)](https://travis-ci.org/disintegration/imaging)
-[![Coverage Status](https://coveralls.io/repos/github/disintegration/imaging/badge.svg?branch=master&service=github)](https://coveralls.io/github/disintegration/imaging?branch=master)
-[![Go Report Card](https://goreportcard.com/badge/github.com/disintegration/imaging)](https://goreportcard.com/report/github.com/disintegration/imaging)
-
-Package imaging provides basic image processing functions (resize, rotate, crop, brightness/contrast adjustments, etc.).
-
-All the image processing functions provided by the package accept any image type that implements `image.Image` interface
-as an input, and return a new image of `*image.NRGBA` type (32bit RGBA colors, non-premultiplied alpha).
-
-## Installation
-
-    go get -u github.com/disintegration/imaging
-
-## Documentation
-
-http://godoc.org/github.com/disintegration/imaging
-
-## Usage examples
-
-A few usage examples can be found below. See the documentation for the full list of supported functions.
-
-### Image resizing
-
-```go
-// Resize srcImage to size = 128x128px using the Lanczos filter.
-dstImage128 := imaging.Resize(srcImage, 128, 128, imaging.Lanczos)
-
-// Resize srcImage to width = 800px preserving the aspect ratio.
-dstImage800 := imaging.Resize(srcImage, 800, 0, imaging.Lanczos)
-
-// Scale down srcImage to fit the 800x600px bounding box.
-dstImageFit := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
-
-// Resize and crop the srcImage to fill the 100x100px area.
-dstImageFill := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
-```
-
-Imaging supports image resizing using various resampling filters. The most notable ones:
-- `Lanczos` - A high-quality resampling filter for photographic images yielding sharp results.
-- `CatmullRom` - A sharp cubic filter that is faster than Lanczos filter while providing similar results.
-- `MitchellNetravali` - A cubic filter that produces smoother results with less ringing artifacts than CatmullRom.
-- `Linear` - Bilinear resampling filter, produces smooth output. Faster than cubic filters.
-- `Box` - Simple and fast averaging filter appropriate for downscaling. When upscaling it's similar to NearestNeighbor.
-- `NearestNeighbor` - Fastest resampling filter, no antialiasing.
-
-The full list of supported filters:  NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. Custom filters can be created using ResampleFilter struct.
-
-**Resampling filters comparison**
-
-Original image:
-
-![srcImage](testdata/branches.png)
-
-The same image resized from 600x400px to 150x100px using different resampling filters.
-From faster (lower quality) to slower (higher quality):
-
-Filter                    | Resize result
---------------------------|---------------------------------------------
-`imaging.NearestNeighbor` | ![dstImage](testdata/out_resize_nearest.png)
-`imaging.Linear`          | ![dstImage](testdata/out_resize_linear.png)
-`imaging.CatmullRom`      | ![dstImage](testdata/out_resize_catrom.png)
-`imaging.Lanczos`         | ![dstImage](testdata/out_resize_lanczos.png)
-
-
-### Gaussian Blur
-
-```go
-dstImage := imaging.Blur(srcImage, 0.5)
-```
-
-Sigma parameter allows to control the strength of the blurring effect.
-
-Original image                     | Sigma = 0.5                            | Sigma = 1.5
------------------------------------|----------------------------------------|---------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_blur_0.5.png) | ![dstImage](testdata/out_blur_1.5.png)
-
-### Sharpening
-
-```go
-dstImage := imaging.Sharpen(srcImage, 0.5)
-```
-
-`Sharpen` uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
-
-Original image                     | Sigma = 0.5                               | Sigma = 1.5
------------------------------------|-------------------------------------------|------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_sharpen_0.5.png) | ![dstImage](testdata/out_sharpen_1.5.png)
-
-### Gamma correction
-
-```go
-dstImage := imaging.AdjustGamma(srcImage, 0.75)
-```
-
-Original image                     | Gamma = 0.75                             | Gamma = 1.25
------------------------------------|------------------------------------------|-----------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_gamma_0.75.png) | ![dstImage](testdata/out_gamma_1.25.png)
-
-### Contrast adjustment
-
-```go
-dstImage := imaging.AdjustContrast(srcImage, 20)
-```
-
-Original image                     | Contrast = 15                              | Contrast = -15
------------------------------------|--------------------------------------------|-------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_contrast_p15.png) | ![dstImage](testdata/out_contrast_m15.png)
-
-### Brightness adjustment
-
-```go
-dstImage := imaging.AdjustBrightness(srcImage, 20)
-```
-
-Original image                     | Brightness = 10                              | Brightness = -10
------------------------------------|----------------------------------------------|---------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_brightness_p10.png) | ![dstImage](testdata/out_brightness_m10.png)
-
-### Saturation adjustment
-
-```go
-dstImage := imaging.AdjustSaturation(srcImage, 20)
-```
-
-Original image                     | Saturation = 30                              | Saturation = -30
------------------------------------|----------------------------------------------|---------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_saturation_p30.png) | ![dstImage](testdata/out_saturation_m30.png)
-
-## FAQ
-
-### Incorrect image orientation after processing (e.g. an image appears rotated after resizing)
-
-Most probably, the given image contains the EXIF orientation tag.
-The stadard `image/*` packages do not support loading and saving
-this kind of information. To fix the issue, try opening images with
-the `AutoOrientation` decode option. If this option is set to `true`,
-the image orientation is changed after decoding, according to the
-orientation tag (if present). Here's the example:
-
-```go
-img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true))
-```
-
-### What's the difference between `imaging` and `gift` packages?
-
-[imaging](https://github.com/disintegration/imaging)
-is designed to be a lightweight and simple image manipulation package.
-It provides basic image processing functions and a few helper functions
-such as `Open` and `Save`. It consistently returns *image.NRGBA image 
-type (8 bits per channel, RGBA).
-
-[gift](https://github.com/disintegration/gift)
-supports more advanced image processing, for example, sRGB/Linear color
-space conversions. It also supports different output image types
-(e.g. 16 bits per channel) and provides easy-to-use API for chaining
-multiple processing steps together.
-
-## Example code
-
-```go
-package main
-
-import (
-	"image"
-	"image/color"
-	"log"
-
-	"github.com/disintegration/imaging"
-)
-
-func main() {
-	// Open a test image.
-	src, err := imaging.Open("testdata/flowers.png")
-	if err != nil {
-		log.Fatalf("failed to open image: %v", err)
-	}
-
-	// Crop the original image to 300x300px size using the center anchor.
-	src = imaging.CropAnchor(src, 300, 300, imaging.Center)
-
-	// Resize the cropped image to width = 200px preserving the aspect ratio.
-	src = imaging.Resize(src, 200, 0, imaging.Lanczos)
-
-	// Create a blurred version of the image.
-	img1 := imaging.Blur(src, 5)
-
-	// Create a grayscale version of the image with higher contrast and sharpness.
-	img2 := imaging.Grayscale(src)
-	img2 = imaging.AdjustContrast(img2, 20)
-	img2 = imaging.Sharpen(img2, 2)
-
-	// Create an inverted version of the image.
-	img3 := imaging.Invert(src)
-
-	// Create an embossed version of the image using a convolution filter.
-	img4 := imaging.Convolve3x3(
-		src,
-		[9]float64{
-			-1, -1, 0,
-			-1, 1, 1,
-			0, 1, 1,
-		},
-		nil,
-	)
-
-	// Create a new image and paste the four produced images into it.
-	dst := imaging.New(400, 400, color.NRGBA{0, 0, 0, 0})
-	dst = imaging.Paste(dst, img1, image.Pt(0, 0))
-	dst = imaging.Paste(dst, img2, image.Pt(0, 200))
-	dst = imaging.Paste(dst, img3, image.Pt(200, 0))
-	dst = imaging.Paste(dst, img4, image.Pt(200, 200))
-
-	// Save the resulting image as JPEG.
-	err = imaging.Save(dst, "testdata/out_example.jpg")
-	if err != nil {
-		log.Fatalf("failed to save image: %v", err)
-	}
-}
-```
-
-Output:
-
-![dstImage](testdata/out_example.jpg)
+# Imaging
+
+Package imaging provides basic image processing functions (resize, rotate, crop, brightness/contrast adjustments, etc.).
+
+All the image processing functions provided by the package accept any image type that implements `image.Image` interface
+as an input, and return a new image of `*image.NRGBA` type (32bit RGBA colors, non-premultiplied alpha).
+
+## Installation
+
+    go get -u github.com/kovidgoyal/imaging
+
+## Documentation
+
+https://pkg.go.dev/github.com/kovidgoyal/imaging
+
+## Usage examples
+
+A few usage examples can be found below. See the documentation for the full list of supported functions.
+
+### Image resizing
+
+```go
+// Resize srcImage to size = 128x128px using the Lanczos filter.
+dstImage128 := imaging.Resize(srcImage, 128, 128, imaging.Lanczos)
+
+// Resize srcImage to width = 800px preserving the aspect ratio.
+dstImage800 := imaging.Resize(srcImage, 800, 0, imaging.Lanczos)
+
+// Scale down srcImage to fit the 800x600px bounding box.
+dstImageFit := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
+
+// Resize and crop the srcImage to fill the 100x100px area.
+dstImageFill := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
+```
+
+Imaging supports image resizing using various resampling filters. The most notable ones:
+- `Lanczos` - A high-quality resampling filter for photographic images yielding sharp results.
+- `CatmullRom` - A sharp cubic filter that is faster than Lanczos filter while providing similar results.
+- `MitchellNetravali` - A cubic filter that produces smoother results with less ringing artifacts than CatmullRom.
+- `Linear` - Bilinear resampling filter, produces smooth output. Faster than cubic filters.
+- `Box` - Simple and fast averaging filter appropriate for downscaling. When upscaling it's similar to NearestNeighbor.
+- `NearestNeighbor` - Fastest resampling filter, no antialiasing.
+
+The full list of supported filters:  NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. Custom filters can be created using ResampleFilter struct.
+
+**Resampling filters comparison**
+
+Original image:
+
+![srcImage](testdata/branches.png)
+
+The same image resized from 600x400px to 150x100px using different resampling filters.
+From faster (lower quality) to slower (higher quality):
+
+Filter                    | Resize result
+--------------------------|---------------------------------------------
+`imaging.NearestNeighbor` | ![dstImage](testdata/out_resize_nearest.png)
+`imaging.Linear`          | ![dstImage](testdata/out_resize_linear.png)
+`imaging.CatmullRom`      | ![dstImage](testdata/out_resize_catrom.png)
+`imaging.Lanczos`         | ![dstImage](testdata/out_resize_lanczos.png)
+
+
+### Gaussian Blur
+
+```go
+dstImage := imaging.Blur(srcImage, 0.5)
+```
+
+Sigma parameter allows to control the strength of the blurring effect.
+
+Original image                     | Sigma = 0.5                            | Sigma = 1.5
+-----------------------------------|----------------------------------------|---------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_blur_0.5.png) | ![dstImage](testdata/out_blur_1.5.png)
+
+### Sharpening
+
+```go
+dstImage := imaging.Sharpen(srcImage, 0.5)
+```
+
+`Sharpen` uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
+
+Original image                     | Sigma = 0.5                               | Sigma = 1.5
+-----------------------------------|-------------------------------------------|------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_sharpen_0.5.png) | ![dstImage](testdata/out_sharpen_1.5.png)
+
+### Gamma correction
+
+```go
+dstImage := imaging.AdjustGamma(srcImage, 0.75)
+```
+
+Original image                     | Gamma = 0.75                             | Gamma = 1.25
+-----------------------------------|------------------------------------------|-----------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_gamma_0.75.png) | ![dstImage](testdata/out_gamma_1.25.png)
+
+### Contrast adjustment
+
+```go
+dstImage := imaging.AdjustContrast(srcImage, 20)
+```
+
+Original image                     | Contrast = 15                              | Contrast = -15
+-----------------------------------|--------------------------------------------|-------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_contrast_p15.png) | ![dstImage](testdata/out_contrast_m15.png)
+
+### Brightness adjustment
+
+```go
+dstImage := imaging.AdjustBrightness(srcImage, 20)
+```
+
+Original image                     | Brightness = 10                              | Brightness = -10
+-----------------------------------|----------------------------------------------|---------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_brightness_p10.png) | ![dstImage](testdata/out_brightness_m10.png)
+
+### Saturation adjustment
+
+```go
+dstImage := imaging.AdjustSaturation(srcImage, 20)
+```
+
+Original image                     | Saturation = 30                              | Saturation = -30
+-----------------------------------|----------------------------------------------|---------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_saturation_p30.png) | ![dstImage](testdata/out_saturation_m30.png)
+
+### Hue adjustment
+
+```go
+dstImage := imaging.AdjustHue(srcImage, 20)
+```
+
+Original image                     | Hue = 60                                     | Hue = -60
+-----------------------------------|----------------------------------------------|---------------------------------------------
+![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_hue_p60.png) | ![dstImage](testdata/out_hue_m60.png)
+
+## FAQ
+
+### Incorrect image orientation after processing (e.g. an image appears rotated after resizing)
+
+Most probably, the given image contains the EXIF orientation tag.
+The standard `image/*` packages do not support loading and saving
+this kind of information. To fix the issue, try opening images with
+the `AutoOrientation` decode option. If this option is set to `true`,
+the image orientation is changed after decoding, according to the
+orientation tag (if present). Here's the example:
+
+```go
+img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true))
+```
+
+### What's the difference between `imaging` and `gift` packages?
+
+[imaging](https://github.com/kovidgoyal/imaging)
+is designed to be a lightweight and simple image manipulation package.
+It provides basic image processing functions and a few helper functions
+such as `Open` and `Save`. It consistently returns *image.NRGBA image 
+type (8 bits per channel, RGBA).
+
+[gift](https://github.com/disintegration/gift)
+supports more advanced image processing, for example, sRGB/Linear color
+space conversions. It also supports different output image types
+(e.g. 16 bits per channel) and provides easy-to-use API for chaining
+multiple processing steps together.
+
+## Example code
+
+```go
+package main
+
+import (
+	"image"
+	"image/color"
+	"log"
+
+	"github.com/kovidgoyal/imaging"
+)
+
+func main() {
+	// Open a test image.
+	src, err := imaging.Open("testdata/flowers.png")
+	if err != nil {
+		log.Fatalf("failed to open image: %v", err)
+	}
+
+	// Crop the original image to 300x300px size using the center anchor.
+	src = imaging.CropAnchor(src, 300, 300, imaging.Center)
+
+	// Resize the cropped image to width = 200px preserving the aspect ratio.
+	src = imaging.Resize(src, 200, 0, imaging.Lanczos)
+
+	// Create a blurred version of the image.
+	img1 := imaging.Blur(src, 5)
+
+	// Create a grayscale version of the image with higher contrast and sharpness.
+	img2 := imaging.Grayscale(src)
+	img2 = imaging.AdjustContrast(img2, 20)
+	img2 = imaging.Sharpen(img2, 2)
+
+	// Create an inverted version of the image.
+	img3 := imaging.Invert(src)
+
+	// Create an embossed version of the image using a convolution filter.
+	img4 := imaging.Convolve3x3(
+		src,
+		[9]float64{
+			-1, -1, 0,
+			-1, 1, 1,
+			0, 1, 1,
+		},
+		nil,
+	)
+
+	// Create a new image and paste the four produced images into it.
+	dst := imaging.New(400, 400, color.NRGBA{0, 0, 0, 0})
+	dst = imaging.Paste(dst, img1, image.Pt(0, 0))
+	dst = imaging.Paste(dst, img2, image.Pt(0, 200))
+	dst = imaging.Paste(dst, img3, image.Pt(200, 0))
+	dst = imaging.Paste(dst, img4, image.Pt(200, 200))
+
+	// Save the resulting image as JPEG.
+	err = imaging.Save(dst, "testdata/out_example.jpg")
+	if err != nil {
+		log.Fatalf("failed to save image: %v", err)
+	}
+}
+```
+
+Output:
+
+![dstImage](testdata/out_example.jpg)
diff --git a/vendor/github.com/disintegration/imaging/adjust.go b/vendor/github.com/kovidgoyal/imaging/adjust.go
similarity index 86%
rename from vendor/github.com/disintegration/imaging/adjust.go
rename to vendor/github.com/kovidgoyal/imaging/adjust.go
index daaf1de860c..971aebc6fe2 100644
--- a/vendor/github.com/disintegration/imaging/adjust.go
+++ b/vendor/github.com/kovidgoyal/imaging/adjust.go
@@ -62,6 +62,10 @@ func Invert(img image.Image) *image.NRGBA {
 //  dstImage = imaging.AdjustSaturation(srcImage, -10) // Decrease image saturation by 10%.
 //
 func AdjustSaturation(img image.Image, percentage float64) *image.NRGBA {
+	if percentage == 0 {
+		return Clone(img)
+	}
+
 	percentage = math.Min(math.Max(percentage, -100), 100)
 	multiplier := 1 + percentage/100
 
@@ -76,6 +80,34 @@ func AdjustSaturation(img image.Image, percentage float64) *image.NRGBA {
 	})
 }
 
+// AdjustHue changes the hue of the image using the shift parameter (measured in degrees) and returns the adjusted image.
+// The shift = 0 (or 360 / -360 / etc.) gives the original image.
+// The shift = 180 (or -180) corresponds to a 180° degree rotation of the color wheel and thus gives the image with its hue inverted for each pixel.
+//
+// Examples:
+//  dstImage = imaging.AdjustHue(srcImage, 90) // Shift Hue by 90°.
+//  dstImage = imaging.AdjustHue(srcImage, -30) // Shift Hue by -30°.
+//
+func AdjustHue(img image.Image, shift float64) *image.NRGBA {
+	if math.Mod(shift, 360) == 0 {
+		return Clone(img)
+	}
+
+	summand := shift / 360
+
+	return AdjustFunc(img, func(c color.NRGBA) color.NRGBA {
+		h, s, l := rgbToHSL(c.R, c.G, c.B)
+		h += summand
+		h = math.Mod(h, 1)
+		//Adding 1 because Golang's Modulo function behaves differently to similar operators in most other languages.
+		if h < 0 {
+			h++
+		}
+		r, g, b := hslToRGB(h, s, l)
+		return color.NRGBA{r, g, b, c.A}
+	})
+}
+
 // AdjustContrast changes the contrast of the image using the percentage parameter and returns the adjusted image.
 // The percentage must be in range (-100, 100). The percentage = 0 gives the original image.
 // The percentage = -100 gives solid gray image.
@@ -86,6 +118,10 @@ func AdjustSaturation(img image.Image, percentage float64) *image.NRGBA {
 //	dstImage = imaging.AdjustContrast(srcImage, 20) // Increase image contrast by 20%.
 //
 func AdjustContrast(img image.Image, percentage float64) *image.NRGBA {
+	if percentage == 0 {
+		return Clone(img)
+	}
+
 	percentage = math.Min(math.Max(percentage, -100.0), 100.0)
 	lut := make([]uint8, 256)
 
@@ -114,6 +150,10 @@ func AdjustContrast(img image.Image, percentage float64) *image.NRGBA {
 //	dstImage = imaging.AdjustBrightness(srcImage, 10) // Increase image brightness by 10%.
 //
 func AdjustBrightness(img image.Image, percentage float64) *image.NRGBA {
+	if percentage == 0 {
+		return Clone(img)
+	}
+
 	percentage = math.Min(math.Max(percentage, -100.0), 100.0)
 	lut := make([]uint8, 256)
 
@@ -134,6 +174,10 @@ func AdjustBrightness(img image.Image, percentage float64) *image.NRGBA {
 //	dstImage = imaging.AdjustGamma(srcImage, 0.7)
 //
 func AdjustGamma(img image.Image, gamma float64) *image.NRGBA {
+	if gamma == 1 {
+		return Clone(img)
+	}
+
 	e := 1.0 / math.Max(gamma, 0.0001)
 	lut := make([]uint8, 256)
 
diff --git a/vendor/github.com/disintegration/imaging/convolution.go b/vendor/github.com/kovidgoyal/imaging/convolution.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/convolution.go
rename to vendor/github.com/kovidgoyal/imaging/convolution.go
diff --git a/vendor/github.com/disintegration/imaging/doc.go b/vendor/github.com/kovidgoyal/imaging/doc.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/doc.go
rename to vendor/github.com/kovidgoyal/imaging/doc.go
diff --git a/vendor/github.com/disintegration/imaging/effects.go b/vendor/github.com/kovidgoyal/imaging/effects.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/effects.go
rename to vendor/github.com/kovidgoyal/imaging/effects.go
diff --git a/vendor/github.com/disintegration/imaging/histogram.go b/vendor/github.com/kovidgoyal/imaging/histogram.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/histogram.go
rename to vendor/github.com/kovidgoyal/imaging/histogram.go
diff --git a/vendor/github.com/disintegration/imaging/io.go b/vendor/github.com/kovidgoyal/imaging/io.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/io.go
rename to vendor/github.com/kovidgoyal/imaging/io.go
diff --git a/vendor/github.com/kovidgoyal/imaging/publish.py b/vendor/github.com/kovidgoyal/imaging/publish.py
new file mode 100644
index 00000000000..3b0317bf4f6
--- /dev/null
+++ b/vendor/github.com/kovidgoyal/imaging/publish.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+# License: GPLv3 Copyright: 2024, Kovid Goyal <kovid at kovidgoyal.net>
+
+import os
+import subprocess
+
+
+def run(*args: str):
+    cp = subprocess.run(args)
+    if cp.returncode != 0:
+        raise SystemExit(cp.returncode)
+
+
+def main():
+    version = input('Enter the version to publish: ')
+    try:
+        ans = input(f'Publish version \033[91m{version}\033[m (y/n): ')
+    except KeyboardInterrupt:
+        ans = 'n'
+    if ans.lower() != 'y':
+        return
+    os.environ['GITHUB_TOKEN'] = open(os.path.join(os.environ['PENV'], 'github-token')).read().strip()
+    run('git', 'tag', '-a', 'v' + version, '-m', f'version {version}')
+    run('git', 'push')
+    run('goreleaser', 'release')
+
+
+if __name__ == '__main__':
+    main()
diff --git a/vendor/github.com/disintegration/imaging/resize.go b/vendor/github.com/kovidgoyal/imaging/resize.go
similarity index 99%
rename from vendor/github.com/disintegration/imaging/resize.go
rename to vendor/github.com/kovidgoyal/imaging/resize.go
index 706435e3dce..963f40c4827 100644
--- a/vendor/github.com/disintegration/imaging/resize.go
+++ b/vendor/github.com/kovidgoyal/imaging/resize.go
@@ -87,6 +87,10 @@ func Resize(img image.Image, width, height int, filter ResampleFilter) *image.NR
 		dstH = int(math.Max(1.0, math.Floor(tmpH+0.5)))
 	}
 
+	if srcW == dstW && srcH == dstH {
+		return Clone(img)
+	}
+
 	if filter.Support <= 0 {
 		// Nearest-neighbor special case.
 		return resizeNearest(img, dstW, dstH)
@@ -98,10 +102,8 @@ func Resize(img image.Image, width, height int, filter ResampleFilter) *image.NR
 	if srcW != dstW {
 		return resizeHorizontal(img, dstW, filter)
 	}
-	if srcH != dstH {
-		return resizeVertical(img, dstH, filter)
-	}
-	return Clone(img)
+	return resizeVertical(img, dstH, filter)
+
 }
 
 func resizeHorizontal(img image.Image, width int, filter ResampleFilter) *image.NRGBA {
diff --git a/vendor/github.com/disintegration/imaging/scanner.go b/vendor/github.com/kovidgoyal/imaging/scanner.go
similarity index 98%
rename from vendor/github.com/disintegration/imaging/scanner.go
rename to vendor/github.com/kovidgoyal/imaging/scanner.go
index 37d92cef886..84de2fc90f2 100644
--- a/vendor/github.com/disintegration/imaging/scanner.go
+++ b/vendor/github.com/kovidgoyal/imaging/scanner.go
@@ -18,7 +18,7 @@ func newScanner(img image.Image) *scanner {
 		h:     img.Bounds().Dy(),
 	}
 	if img, ok := img.(*image.Paletted); ok {
-		s.palette = make([]color.NRGBA, len(img.Palette))
+		s.palette = make([]color.NRGBA, max(256, len(img.Palette)))
 		for i := 0; i < len(img.Palette); i++ {
 			s.palette[i] = color.NRGBAModel.Convert(img.Palette[i]).(color.NRGBA)
 		}
diff --git a/vendor/github.com/kovidgoyal/imaging/session.vim b/vendor/github.com/kovidgoyal/imaging/session.vim
new file mode 100644
index 00000000000..76924354f1f
--- /dev/null
+++ b/vendor/github.com/kovidgoyal/imaging/session.vim
@@ -0,0 +1,2 @@
+" Empty for the moment
+
diff --git a/vendor/github.com/disintegration/imaging/tools.go b/vendor/github.com/kovidgoyal/imaging/tools.go
similarity index 98%
rename from vendor/github.com/disintegration/imaging/tools.go
rename to vendor/github.com/kovidgoyal/imaging/tools.go
index 0ec19a039cc..9591ebc5ae2 100644
--- a/vendor/github.com/disintegration/imaging/tools.go
+++ b/vendor/github.com/kovidgoyal/imaging/tools.go
@@ -96,6 +96,10 @@ func Crop(img image.Image, rect image.Rectangle) *image.NRGBA {
 	if r.Empty() {
 		return &image.NRGBA{}
 	}
+	if r.Eq(img.Bounds().Sub(img.Bounds().Min)) {
+		return Clone(img)
+	}
+
 	src := newScanner(img)
 	dst := image.NewNRGBA(image.Rect(0, 0, r.Dx(), r.Dy()))
 	rowSize := r.Dx() * 4
@@ -133,6 +137,10 @@ func Paste(background, img image.Image, pos image.Point) *image.NRGBA {
 	if interRect.Empty() {
 		return dst
 	}
+	if interRect.Eq(dst.Bounds()) {
+		return Clone(img)
+	}
+
 	src := newScanner(img)
 	parallel(interRect.Min.Y, interRect.Max.Y, func(ys <-chan int) {
 		for y := range ys {
diff --git a/vendor/github.com/disintegration/imaging/transform.go b/vendor/github.com/kovidgoyal/imaging/transform.go
similarity index 100%
rename from vendor/github.com/disintegration/imaging/transform.go
rename to vendor/github.com/kovidgoyal/imaging/transform.go
diff --git a/vendor/github.com/disintegration/imaging/utils.go b/vendor/github.com/kovidgoyal/imaging/utils.go
similarity index 88%
rename from vendor/github.com/disintegration/imaging/utils.go
rename to vendor/github.com/kovidgoyal/imaging/utils.go
index 6c7af1a5188..f650c05bce1 100644
--- a/vendor/github.com/disintegration/imaging/utils.go
+++ b/vendor/github.com/kovidgoyal/imaging/utils.go
@@ -5,8 +5,17 @@ import (
 	"math"
 	"runtime"
 	"sync"
+	"sync/atomic"
 )
 
+var maxProcs int64
+
+// SetMaxProcs limits the number of concurrent processing goroutines to the given value.
+// A value <= 0 clears the limit.
+func SetMaxProcs(value int) {
+	atomic.StoreInt64(&maxProcs, int64(value))
+}
+
 // parallel processes the data in separate goroutines.
 func parallel(start, stop int, fn func(<-chan int)) {
 	count := stop - start
@@ -15,6 +24,10 @@ func parallel(start, stop int, fn func(<-chan int)) {
 	}
 
 	procs := runtime.GOMAXPROCS(0)
+	limit := int(atomic.LoadInt64(&maxProcs))
+	if procs > limit && limit > 0 {
+		procs = limit
+	}
 	if procs > count {
 		procs = count
 	}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
index 843b4fa2fb1..c64f8beca71 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
@@ -4,18 +4,16 @@
 package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
 
 import (
-	"io"
 	"net/http"
 	"time"
 
 	"github.com/felixge/httpsnoop"
 
+	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv"
 	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil"
 	"go.opentelemetry.io/otel"
-	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/metric"
 	"go.opentelemetry.io/otel/propagation"
-	semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
 	"go.opentelemetry.io/otel/trace"
 )
 
@@ -35,6 +33,7 @@ type middleware struct {
 	publicEndpoint    bool
 	publicEndpointFn  func(*http.Request) bool
 
+	traceSemconv         semconv.HTTPServer
 	requestBytesCounter  metric.Int64Counter
 	responseBytesCounter metric.Int64Counter
 	serverLatencyMeasure metric.Float64Histogram
@@ -56,6 +55,8 @@ func NewHandler(handler http.Handler, operation string, opts ...Option) http.Han
 func NewMiddleware(operation string, opts ...Option) func(http.Handler) http.Handler {
 	h := middleware{
 		operation: operation,
+
+		traceSemconv: semconv.NewHTTPServer(),
 	}
 
 	defaultOpts := []Option{
@@ -132,12 +133,9 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http
 
 	ctx := h.propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header))
 	opts := []trace.SpanStartOption{
-		trace.WithAttributes(semconvutil.HTTPServerRequest(h.server, r)...),
-	}
-	if h.server != "" {
-		hostAttr := semconv.NetHostName(h.server)
-		opts = append(opts, trace.WithAttributes(hostAttr))
+		trace.WithAttributes(h.traceSemconv.RequestTraceAttrs(h.server, r)...),
 	}
+
 	opts = append(opts, h.spanStartOptions...)
 	if h.publicEndpoint || (h.publicEndpointFn != nil && h.publicEndpointFn(r.WithContext(ctx))) {
 		opts = append(opts, trace.WithNewRoot())
@@ -213,7 +211,14 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http
 
 	next.ServeHTTP(w, r.WithContext(ctx))
 
-	setAfterServeAttributes(span, bw.read.Load(), rww.written, rww.statusCode, bw.err, rww.err)
+	span.SetStatus(semconv.ServerStatus(rww.statusCode))
+	span.SetAttributes(h.traceSemconv.ResponseTraceAttrs(semconv.ResponseTelemetry{
+		StatusCode: rww.statusCode,
+		ReadBytes:  bw.read.Load(),
+		ReadError:  bw.err,
+		WriteBytes: rww.written,
+		WriteError: rww.err,
+	})...)
 
 	// Add metrics
 	attributes := append(labeler.Get(), semconvutil.HTTPServerRequestMetrics(h.server, r)...)
@@ -230,37 +235,11 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http
 	h.serverLatencyMeasure.Record(ctx, elapsedTime, o)
 }
 
-func setAfterServeAttributes(span trace.Span, read, wrote int64, statusCode int, rerr, werr error) {
-	attributes := []attribute.KeyValue{}
-
-	// TODO: Consider adding an event after each read and write, possibly as an
-	// option (defaulting to off), so as to not create needlessly verbose spans.
-	if read > 0 {
-		attributes = append(attributes, ReadBytesKey.Int64(read))
-	}
-	if rerr != nil && rerr != io.EOF {
-		attributes = append(attributes, ReadErrorKey.String(rerr.Error()))
-	}
-	if wrote > 0 {
-		attributes = append(attributes, WroteBytesKey.Int64(wrote))
-	}
-	if statusCode > 0 {
-		attributes = append(attributes, semconv.HTTPStatusCode(statusCode))
-	}
-	span.SetStatus(semconvutil.HTTPServerStatus(statusCode))
-
-	if werr != nil && werr != io.EOF {
-		attributes = append(attributes, WriteErrorKey.String(werr.Error()))
-	}
-	span.SetAttributes(attributes...)
-}
-
 // WithRouteTag annotates spans and metrics with the provided route name
 // with HTTP route attribute.
 func WithRouteTag(route string, h http.Handler) http.Handler {
+	attr := semconv.NewHTTPServer().Route(route)
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		attr := semconv.HTTPRouteKey.String(route)
-
 		span := trace.SpanFromContext(r.Context())
 		span.SetAttributes(attr)
 
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go
new file mode 100644
index 00000000000..9be3feef29e
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go
@@ -0,0 +1,69 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv"
+
+import (
+	"fmt"
+	"net/http"
+
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+)
+
+type ResponseTelemetry struct {
+	StatusCode int
+	ReadBytes  int64
+	ReadError  error
+	WriteBytes int64
+	WriteError error
+}
+
+type HTTPServer interface {
+	// RequestTraceAttrs returns trace attributes for an HTTP request received by a
+	// server.
+	//
+	// The server must be the primary server name if it is known. For example this
+	// would be the ServerName directive
+	// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
+	// server, and the server_name directive
+	// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
+	// nginx server. More generically, the primary server name would be the host
+	// header value that matches the default virtual host of an HTTP server. It
+	// should include the host identifier and if a port is used to route to the
+	// server that port identifier should be included as an appropriate port
+	// suffix.
+	//
+	// If the primary server name is not known, server should be an empty string.
+	// The req Host will be used to determine the server instead.
+	RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue
+
+	// ResponseTraceAttrs returns trace attributes for telemetry from an HTTP response.
+	//
+	// If any of the fields in the ResponseTelemetry are not set the attribute will be omitted.
+	ResponseTraceAttrs(ResponseTelemetry) []attribute.KeyValue
+
+	// Route returns the attribute for the route.
+	Route(string) attribute.KeyValue
+}
+
+// var warnOnce = sync.Once{}
+
+func NewHTTPServer() HTTPServer {
+	// TODO (#5331): Detect version based on environment variable OTEL_HTTP_CLIENT_COMPATIBILITY_MODE.
+	// TODO (#5331): Add warning of use of a deprecated version of Semantic Versions.
+	return oldHTTPServer{}
+}
+
+// ServerStatus returns a span status code and message for an HTTP status code
+// value returned by a server. Status codes in the 400-499 range are not
+// returned as errors.
+func ServerStatus(code int) (codes.Code, string) {
+	if code < 100 || code >= 600 {
+		return codes.Error, fmt.Sprintf("Invalid HTTP status code %d", code)
+	}
+	if code >= 500 {
+		return codes.Error, ""
+	}
+	return codes.Unset, ""
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go
new file mode 100644
index 00000000000..c92076bc3d9
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go
@@ -0,0 +1,49 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv"
+
+import (
+	"net"
+	"strconv"
+	"strings"
+)
+
+// splitHostPort splits a network address hostport of the form "host",
+// "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port",
+// "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and
+// port.
+//
+// An empty host is returned if it is not provided or unparsable. A negative
+// port is returned if it is not provided or unparsable.
+func splitHostPort(hostport string) (host string, port int) {
+	port = -1
+
+	if strings.HasPrefix(hostport, "[") {
+		addrEnd := strings.LastIndex(hostport, "]")
+		if addrEnd < 0 {
+			// Invalid hostport.
+			return
+		}
+		if i := strings.LastIndex(hostport[addrEnd:], ":"); i < 0 {
+			host = hostport[1:addrEnd]
+			return
+		}
+	} else {
+		if i := strings.LastIndex(hostport, ":"); i < 0 {
+			host = hostport
+			return
+		}
+	}
+
+	host, pStr, err := net.SplitHostPort(hostport)
+	if err != nil {
+		return
+	}
+
+	p, err := strconv.ParseUint(pStr, 10, 16)
+	if err != nil {
+		return
+	}
+	return host, int(p)
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go
new file mode 100644
index 00000000000..d753083b7b4
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go
@@ -0,0 +1,75 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv"
+
+import (
+	"io"
+	"net/http"
+
+	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil"
+	"go.opentelemetry.io/otel/attribute"
+	semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
+)
+
+type oldHTTPServer struct{}
+
+var _ HTTPServer = oldHTTPServer{}
+
+// RequestTraceAttrs returns trace attributes for an HTTP request received by a
+// server.
+//
+// The server must be the primary server name if it is known. For example this
+// would be the ServerName directive
+// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache
+// server, and the server_name directive
+// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an
+// nginx server. More generically, the primary server name would be the host
+// header value that matches the default virtual host of an HTTP server. It
+// should include the host identifier and if a port is used to route to the
+// server that port identifier should be included as an appropriate port
+// suffix.
+//
+// If the primary server name is not known, server should be an empty string.
+// The req Host will be used to determine the server instead.
+func (o oldHTTPServer) RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue {
+	return semconvutil.HTTPServerRequest(server, req)
+}
+
+// ResponseTraceAttrs returns trace attributes for telemetry from an HTTP response.
+//
+// If any of the fields in the ResponseTelemetry are not set the attribute will be omitted.
+func (o oldHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue {
+	attributes := []attribute.KeyValue{}
+
+	if resp.ReadBytes > 0 {
+		attributes = append(attributes, semconv.HTTPRequestContentLength(int(resp.ReadBytes)))
+	}
+	if resp.ReadError != nil && resp.ReadError != io.EOF {
+		// This is not in the semantic conventions, but is historically provided
+		attributes = append(attributes, attribute.String("http.read_error", resp.ReadError.Error()))
+	}
+	if resp.WriteBytes > 0 {
+		attributes = append(attributes, semconv.HTTPResponseContentLength(int(resp.WriteBytes)))
+	}
+	if resp.StatusCode > 0 {
+		attributes = append(attributes, semconv.HTTPStatusCode(resp.StatusCode))
+	}
+	if resp.WriteError != nil && resp.WriteError != io.EOF {
+		// This is not in the semantic conventions, but is historically provided
+		attributes = append(attributes, attribute.String("http.write_error", resp.WriteError.Error()))
+	}
+
+	return attributes
+}
+
+// Route returns the attribute for the route.
+func (o oldHTTPServer) Route(route string) attribute.KeyValue {
+	return semconv.HTTPRoute(route)
+}
+
+// HTTPStatusCode returns the attribute for the HTTP status code.
+// This is a temporary function needed by metrics.  This will be removed when MetricsRequest is added.
+func HTTPStatusCode(status int) attribute.KeyValue {
+	return semconv.HTTPStatusCode(status)
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
index 08fb4fe17f8..0fcc279de94 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
@@ -5,7 +5,7 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http
 
 // Version is the current release version of the otelhttp instrumentation.
 func Version() string {
-	return "0.50.0"
+	return "0.51.0"
 	// This string is updated by the pre_release.sh script during release
 }
 
diff --git a/vendor/golang.org/x/sync/semaphore/semaphore.go b/vendor/golang.org/x/sync/semaphore/semaphore.go
index 30f632c577b..b618162aab6 100644
--- a/vendor/golang.org/x/sync/semaphore/semaphore.go
+++ b/vendor/golang.org/x/sync/semaphore/semaphore.go
@@ -35,11 +35,25 @@ type Weighted struct {
 // Acquire acquires the semaphore with a weight of n, blocking until resources
 // are available or ctx is done. On success, returns nil. On failure, returns
 // ctx.Err() and leaves the semaphore unchanged.
-//
-// If ctx is already done, Acquire may still succeed without blocking.
 func (s *Weighted) Acquire(ctx context.Context, n int64) error {
+	done := ctx.Done()
+
 	s.mu.Lock()
+	select {
+	case <-done:
+		// ctx becoming done has "happened before" acquiring the semaphore,
+		// whether it became done before the call began or while we were
+		// waiting for the mutex. We prefer to fail even if we could acquire
+		// the mutex without blocking.
+		s.mu.Unlock()
+		return ctx.Err()
+	default:
+	}
 	if s.size-s.cur >= n && s.waiters.Len() == 0 {
+		// Since we hold s.mu and haven't synchronized since checking done, if
+		// ctx becomes done before we return here, it becoming done must have
+		// "happened concurrently" with this call - it cannot "happen before"
+		// we return in this branch. So, we're ok to always acquire here.
 		s.cur += n
 		s.mu.Unlock()
 		return nil
@@ -48,7 +62,7 @@ func (s *Weighted) Acquire(ctx context.Context, n int64) error {
 	if n > s.size {
 		// Don't make other Acquire calls block on one that's doomed to fail.
 		s.mu.Unlock()
-		<-ctx.Done()
+		<-done
 		return ctx.Err()
 	}
 
@@ -58,14 +72,14 @@ func (s *Weighted) Acquire(ctx context.Context, n int64) error {
 	s.mu.Unlock()
 
 	select {
-	case <-ctx.Done():
-		err := ctx.Err()
+	case <-done:
 		s.mu.Lock()
 		select {
 		case <-ready:
-			// Acquired the semaphore after we were canceled.  Rather than trying to
-			// fix up the queue, just pretend we didn't notice the cancelation.
-			err = nil
+			// Acquired the semaphore after we were canceled.
+			// Pretend we didn't and put the tokens back.
+			s.cur -= n
+			s.notifyWaiters()
 		default:
 			isFront := s.waiters.Front() == elem
 			s.waiters.Remove(elem)
@@ -75,9 +89,19 @@ func (s *Weighted) Acquire(ctx context.Context, n int64) error {
 			}
 		}
 		s.mu.Unlock()
-		return err
+		return ctx.Err()
 
 	case <-ready:
+		// Acquired the semaphore. Check that ctx isn't already done.
+		// We check the done channel instead of calling ctx.Err because we
+		// already have the channel, and ctx.Err is O(n) with the nesting
+		// depth of ctx.
+		select {
+		case <-done:
+			s.Release(n)
+			return ctx.Err()
+		default:
+		}
 		return nil
 	}
 }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index a72220c8163..a6fe0ee9130 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -370,7 +370,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1
 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1
 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1
 github.com/cs3org/go-cs3apis/cs3/types/v1beta1
-# github.com/cs3org/reva/v2 v2.19.2-0.20240422150349-51ab7655f858
+# github.com/cs3org/reva/v2 v2.19.2-0.20240426071117-7ed0671f9e0b
 ## explicit; go 1.21
 github.com/cs3org/reva/v2/cmd/revad/internal/grace
 github.com/cs3org/reva/v2/cmd/revad/runtime
@@ -758,9 +758,6 @@ github.com/dgryski/go-rendezvous
 # github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
 ## explicit; go 1.18
 github.com/dhowden/tag
-# github.com/disintegration/imaging v1.6.2
-## explicit
-github.com/disintegration/imaging
 # github.com/dlclark/regexp2 v1.4.0
 ## explicit
 github.com/dlclark/regexp2
@@ -1256,6 +1253,9 @@ github.com/klauspost/compress/s2
 # github.com/klauspost/cpuid/v2 v2.2.6
 ## explicit; go 1.15
 github.com/klauspost/cpuid/v2
+# github.com/kovidgoyal/imaging v1.6.3
+## explicit; go 1.21
+github.com/kovidgoyal/imaging
 # github.com/leodido/go-urn v1.4.0
 ## explicit; go 1.18
 github.com/leodido/go-urn
@@ -1947,9 +1947,10 @@ go.opencensus.io/trace/tracestate
 ## explicit; go 1.20
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal
-# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0
+# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0
 ## explicit; go 1.21
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil
 # go.opentelemetry.io/contrib/zpages v0.49.0
 ## explicit; go 1.20
@@ -2112,7 +2113,7 @@ golang.org/x/net/trace
 ## explicit; go 1.18
 golang.org/x/oauth2
 golang.org/x/oauth2/internal
-# golang.org/x/sync v0.6.0
+# golang.org/x/sync v0.7.0
 ## explicit; go 1.18
 golang.org/x/sync/errgroup
 golang.org/x/sync/semaphore


Test patch:
diff --git a/services/thumbnails/pkg/thumbnail/processor_test.go b/services/thumbnails/pkg/thumbnail/processor_test.go
index febda33b817..893931a8795 100644
--- a/services/thumbnails/pkg/thumbnail/processor_test.go
+++ b/services/thumbnails/pkg/thumbnail/processor_test.go
@@ -3,7 +3,7 @@ package thumbnail_test
 import (
 	"testing"
 
-	"github.com/disintegration/imaging"
+	"github.com/kovidgoyal/imaging"
 	tAssert "github.com/stretchr/testify/assert"
 
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/thumbnail"
diff --git a/tests/acceptance/features/apiSharingNg/enableDisableShareSync.feature b/tests/acceptance/features/apiSharingNg/enableDisableShareSync.feature
index 05918466d59..76e82e07852 100644
--- a/tests/acceptance/features/apiSharingNg/enableDisableShareSync.feature
+++ b/tests/acceptance/features/apiSharingNg/enableDisableShareSync.feature
@@ -300,7 +300,8 @@ Feature:  enable or disable sync of incoming shares
 
   @issue-8724
   Scenario: try to enable share sync of a non-existent resource
-    When user "Brian" tries to enable share sync of a non-existent resource using the Graph API
+    Given user "Brian" has disabled the auto-sync share
+    When user "Brian" tries to enable share sync of a resource "nonexistent" using the Graph API
     Then the HTTP status code should be "400"
     And the JSON data of the response should match
       """
@@ -334,3 +335,41 @@ Feature:  enable or disable sync of incoming shares
         }
       }
       """
+
+
+  Scenario: try to enable share sync with empty resource id
+    Given user "Brian" has disabled the auto-sync share
+    When user "Brian" tries to enable share sync of a resource "" using the Graph API
+    Then the HTTP status code should be "400"
+    And the JSON data of the response should match
+      """
+      {
+        "type": "object",
+        "required": ["error"],
+        "properties": {
+          "error": {
+            "type": "object",
+            "required": [
+              "code",
+              "innererror",
+              "message"
+            ],
+            "properties": {
+              "code" : {
+                "const": "invalidRequest"
+              },
+              "innererror" : {
+                "type": "object",
+                "required": [
+                  "date",
+                  "request-id"
+                ]
+              },
+              "message" : {
+                "const": "invalid id"
+              }
+            }
+          }
+        }
+      }
+      """
diff --git a/tests/acceptance/features/bootstrap/SharingNgContext.php b/tests/acceptance/features/bootstrap/SharingNgContext.php
index 80fa52c967a..c6bfad345ad 100644
--- a/tests/acceptance/features/bootstrap/SharingNgContext.php
+++ b/tests/acceptance/features/bootstrap/SharingNgContext.php
@@ -165,7 +165,7 @@ class SharingNgContext implements Context {
 	public function userTriesToListThePermissionsOfSpaceUsingPermissionsEndpointOfTheGraphApi(string $user, string $space, string $spaceOwner):void {
 		$spaceId = ($this->spacesContext->getSpaceByName($spaceOwner, $space))["id"];
 		$itemId = $this->spacesContext->getResourceId($spaceOwner, $space, '');
-		
+
 		$this->featureContext->setResponse(
 			GraphHelper::getPermissionsList(
 				$this->featureContext->getBaseUrl(),
@@ -741,20 +741,24 @@ class SharingNgContext implements Context {
 	}
 
 	/**
-	 * @When user :user tries to enable share sync of a non-existent resource using the Graph API
+	 * @When user :user tries to enable share sync of a resource :resource using the Graph API
 	 *
 	 * @param string $user
+	 * @param string $resource
 	 *
 	 * @return void
+	 * @throws Exception|GuzzleException
 	 */
-	public function userTriesToEnablsShareSyncOfNonExistentResourceUsingTheGraphApi(string $user):void {
+	public function userTriesToEnableShareSyncOfResourceUsingTheGraphApi(string $user, string $resource):void {
 		$shareSpaceId = FeatureContext::SHARES_SPACE_ID;
+		$itemId = ($resource === 'nonexistent') ? WebDavHelper::generateUUIDv4() : '';
+
 		$response =  GraphHelper::enableShareSync(
 			$this->featureContext->getBaseUrl(),
 			$this->featureContext->getStepLineRef(),
 			$this->featureContext->getActualUsername($user),
 			$this->featureContext->getPasswordForUser($user),
-			WebDavHelper::generateUUIDv4(),
+			$itemId,
 			$shareSpaceId
 		);
 		$this->featureContext->setResponse($response);