nextcloud / server

☁️ Nextcloud server, a safe home for all your data
https://nextcloud.com
GNU Affero General Public License v3.0
27.32k stars 4.06k forks source link

[Bug]: Error "Argument #3 ($paramType) must be of type string, null given" within WebDav SEARCH metadata API #45253

Open arquitecturatic opened 5 months ago

arquitecturatic commented 5 months ago

⚠️ This issue respects the following points: ⚠️

Bug description

There are errors in new metadata API when you search files by metadata like WebDAV SEARCH based on metadata.

Steps to reproduce

  1. Create container with "docker run -d -p 8082:80 nextcloud:29.0.0"
  2. Configure all needed with the wizard, not extra settings.
  3. Install new nextcloud app to enable metadata api in this case "metadata" app file. metadata.zip
  4. Update the metadata to any file, example Readme.md. It is works. curl-update-metadata.txt
  5. Search by metadata, it is not works. The resonse from server is "Argument 3 ($paramType) must be of type string, null given", curl-search-webdav.txt

Expected behavior

I expect get all files that have metadata.

Installation method

Community Docker image

Nextcloud Server version

29

Operating system

Debian/Ubuntu

PHP engine version

None

Web server

None

Database engine version

SQlite

Is this bug present after an update or on a fresh install?

Fresh Nextcloud Server install

Are you using the Nextcloud Server Encryption module?

Encryption is Disabled

What user-backends are you using?

Configuration report

{
    "system": {
        "htaccess.RewriteBase": "\/",
        "memcache.local": "\\OC\\Memcache\\APCu",
        "apps_paths": [
            {
                "path": "\/var\/www\/html\/apps",
                "url": "\/apps",
                "writable": false
            },
            {
                "path": "\/var\/www\/html\/custom_apps",
                "url": "\/custom_apps",
                "writable": true
            }
        ],
        "upgrade.disable-web": true,
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "172.16.100.6:8082"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "sqlite3",
        "version": "29.0.0.19",
        "overwrite.cli.url": "http:\/\/x.x.x.x:8082",
        "installed": true
    }
}

List of activated Apps

Enabled:
  - activity: 2.21.1
  - circles: 29.0.0-dev
  - cloud_federation_api: 1.12.0
  - comments: 1.19.0
  - contactsinteraction: 1.10.0
  - dashboard: 7.9.0
  - dav: 1.30.1
  - federatedfilesharing: 1.19.0
  - federation: 1.19.0
  - files: 2.1.0
  - files_downloadlimit: 2.0.0
  - files_pdfviewer: 2.10.0
  - files_reminders: 1.2.0
  - files_sharing: 1.21.0
  - files_trashbin: 1.19.0
  - files_versions: 1.22.0
  - firstrunwizard: 2.18.0
  - logreader: 2.14.0
  - lookup_server_connector: 1.17.0
  - metadata: 1.0.0
  - nextcloud_announcements: 1.18.0
  - notifications: 2.17.0
  - oauth2: 1.17.0
  - password_policy: 1.19.0
  - photos: 2.5.0
  - privacy: 1.13.0
  - provisioning_api: 1.19.0
  - recommendations: 2.1.0
  - related_resources: 1.4.0
  - serverinfo: 1.19.0
  - settings: 1.12.0
  - sharebymail: 1.19.0
  - support: 1.12.0
  - survey_client: 1.17.0
  - systemtags: 1.19.0
  - text: 3.10.0
  - theming: 2.4.0
  - twofactor_backupcodes: 1.18.0
  - updatenotification: 1.19.1
  - user_status: 1.9.0
  - viewer: 2.3.0
  - weather_status: 1.9.0
  - workflowengine: 2.11.0
Disabled:
  - admin_audit: 1.19.0
  - bruteforcesettings: 2.9.0
  - encryption: 2.17.0
  - files_external: 1.21.0
  - suspicious_login: 7.0.0
  - twofactor_totp: 11.0.0-dev
  - user_ldap: 1.20.0

Nextcloud Signing status

No response

Nextcloud Logs

{"reqId":"mUxVYMjyZMaPHeC3xgGK","level":3,"time":"2024-05-10T13:56:04+00:00","remoteAddr":"172.16.100.9","user":"demo","app":"webdav","method":"SEARCH","url":"/remote.php/dav","message":"OC\\Files\\Cache\\SearchBuilder::getParameterForValue(): Argument #3 ($paramType) must be of type string, null given, called in /var/www/html/lib/private/Files/Cache/SearchBuilder.php on line 190","userAgent":"curl/8.4.0","version":"29.0.0.19","exception":{"Exception":"TypeError","Message":"OC\\Files\\Cache\\SearchBuilder::getParameterForValue(): Argument #3 ($paramType) must be of type string, null given, called in /var/www/html/lib/private/Files/Cache/SearchBuilder.php on line 190","Code":0,"Trace":[{"file":"/var/www/html/lib/private/Files/Cache/SearchBuilder.php","line":190,"function":"getParameterForValue","class":"OC\\Files\\Cache\\SearchBuilder","type":"->","args":[["OC\\Files\\Cache\\CacheQueryBuilder"],1,null]},{"file":"/var/www/html/lib/private/Files/Cache/SearchBuilder.php","line":170,"function":"searchComparisonToDBExpr","class":"OC\\Files\\Cache\\SearchBuilder","type":"->","args":[["OC\\Files\\Cache\\CacheQueryBuilder"],"*** sensitive parameters replaced ***",["iLike","like","eq","gt","gte","And 4 more entries, set log level to debug to see all entries"],["OC\\FilesMetadata\\MetadataQuery"]]},{"file":"/var/www/html/lib/private/Files/Cache/SearchBuilder.php","line":137,"function":"searchOperatorToDBExpr","class":"OC\\Files\\Cache\\SearchBuilder","type":"->","args":[["OC\\Files\\Cache\\CacheQueryBuilder"],"*** sensitive parameters replaced ***",["OC\\FilesMetadata\\MetadataQuery"]]},{"function":"OC\\Files\\Cache\\{closure}","class":"OC\\Files\\Cache\\SearchBuilder","type":"->","args":["*** sensitive parameters replaced ***"]},{"file":"/var/www/html/lib/private/Files/Cache/SearchBuilder.php","line":136,"function":"array_map","args":[["Closure"],["*** sensitive parameters replaced ***","*** sensitive parameters replaced ***",["OC\\Files\\Search\\SearchBinaryOperator"]]]},{"file":"/var/www/html/lib/private/Files/Cache/SearchBuilder.php","line":163,"function":"searchOperatorArrayToDBExprArray","class":"OC\\Files\\Cache\\SearchBuilder","type":"->","args":[["OC\\Files\\Cache\\CacheQueryBuilder"],["*** sensitive parameters replaced ***","*** sensitive parameters replaced ***",["OC\\Files\\Search\\SearchBinaryOperator"]],["OC\\FilesMetadata\\MetadataQuery"]]},{"file":"/var/www/html/lib/private/Files/Cache/QuerySearchHelper.php","line":89,"function":"searchOperatorToDBExpr","class":"OC\\Files\\Cache\\SearchBuilder","type":"->","args":[["OC\\Files\\Cache\\CacheQueryBuilder"],["OC\\Files\\Search\\SearchBinaryOperator"],["OC\\FilesMetadata\\MetadataQuery"]]},{"file":"/var/www/html/lib/private/Files/Cache/QuerySearchHelper.php","line":192,"function":"applySearchConstraints","class":"OC\\Files\\Cache\\QuerySearchHelper","type":"->","args":[["OC\\Files\\Cache\\CacheQueryBuilder"],["OC\\Files\\Search\\SearchQuery"],[["OC\\Files\\Cache\\Wrapper\\CacheJail"]],["OC\\FilesMetadata\\MetadataQuery"]]},{"file":"/var/www/html/lib/private/Files/Node/Folder.php","line":235,"function":"searchInCaches","class":"OC\\Files\\Cache\\QuerySearchHelper","type":"->","args":[["OC\\Files\\Search\\SearchQuery"],[["OC\\Files\\Cache\\Wrapper\\CacheJail"]]]},{"file":"/var/www/html/apps/dav/lib/Files/FileSearchBackend.php","line":176,"function":"search","class":"OC\\Files\\Node\\Folder","type":"->","args":[["OC\\Files\\Search\\SearchQuery"]]},{"file":"/var/www/html/apps/dav/lib/Files/LazySearchBackend.php","line":62,"function":"search","class":"OCA\\DAV\\Files\\FileSearchBackend","type":"->","args":[["SearchDAV\\Query\\Query",[],[["SearchDAV\\XML\\Scope","/files/demo/","infinity","/files/demo/"]],["SearchDAV\\Query\\Operator","{DAV:}gt",[["SearchDAV\\Backend\\SearchPropertyDefinition",true,true,true,true,"{http://www.w3.org/2001/XMLSchema}integer","{http://nextcloud.org/ns}metadata-myapp-test"],["SearchDAV\\XML\\Literal","1"]]],[],["SearchDAV\\XML\\Limit",0,0]]]},{"file":"/var/www/html/3rdparty/icewind/searchdav/src/DAV/SearchHandler.php","line":82,"function":"search","class":"OCA\\DAV\\Files\\LazySearchBackend","type":"->","args":[["SearchDAV\\Query\\Query",[],[["SearchDAV\\XML\\Scope","/files/demo/","infinity","/files/demo/"]],["SearchDAV\\Query\\Operator","{DAV:}gt",[["SearchDAV\\Backend\\SearchPropertyDefinition",true,true,true,true,"{http://www.w3.org/2001/XMLSchema}integer","{http://nextcloud.org/ns}metadata-myapp-test"],["SearchDAV\\XML\\Literal","1"]]],[],["SearchDAV\\XML\\Limit",0,0]]]},{"file":"/var/www/html/3rdparty/icewind/searchdav/src/DAV/SearchPlugin.php","line":119,"function":"handleSearchRequest","class":"SearchDAV\\DAV\\SearchHandler","type":"->","args":[[["SearchDAV\\XML\\BasicSearch",["{http://nextcloud.org/ns}metadata-operacion"],[["SearchDAV\\XML\\Scope","/files/demo/","infinity","/files/demo/"]],["SearchDAV\\XML\\Operator","{DAV:}gt",["{http://nextcloud.org/ns}metadata-myapp-test",["SearchDAV\\XML\\Literal","1"]]],[],["SearchDAV\\XML\\Limit",0,0]]],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/event/lib/WildcardEmitterTrait.php","line":89,"function":"searchHandler","class":"SearchDAV\\DAV\\SearchPlugin","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":472,"function":"emit","class":"Sabre\\DAV\\Server","type":"->","args":["method:SEARCH",[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":253,"function":"invokeMethod","class":"Sabre\\DAV\\Server","type":"->","args":[["Sabre\\HTTP\\Request"],["Sabre\\HTTP\\Response"]]},{"file":"/var/www/html/3rdparty/sabre/dav/lib/DAV/Server.php","line":321,"function":"start","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/lib/Server.php","line":374,"function":"exec","class":"Sabre\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/apps/dav/appinfo/v2/remote.php","line":35,"function":"exec","class":"OCA\\DAV\\Server","type":"->","args":[]},{"file":"/var/www/html/remote.php","line":172,"args":["/var/www/html/apps/dav/appinfo/v2/remote.php"],"function":"require_once"}],"File":"/var/www/html/lib/private/Files/Cache/SearchBuilder.php","Line":326,"message":"OC\\Files\\Cache\\SearchBuilder::getParameterForValue(): Argument #3 ($paramType) must be of type string, null given, called in /var/www/html/lib/private/Files/Cache/SearchBuilder.php on line 190","exception":{},"CustomMessage":"OC\\Files\\Cache\\SearchBuilder::getParameterForValue(): Argument #3 ($paramType) must be of type string, null given, called in /var/www/html/lib/private/Files/Cache/SearchBuilder.php on line 190"}}

Additional info

Suggested changes: Add method getMetadataTypeField to file "lib/private/FilesMetadata/MetadataQuery.php"

 public function getMetadataTypeField(string $metadataKey): string {
                return $this->knownMetadata->getType($metadataKey);
}

Modify the method getExtraOperatorField in lib/private/Files/Cache/SearchBuilder.php

 private function getExtraOperatorField(ISearchComparison $operator, IMetadataQuery $metadataQuery): array {
                if($operator->getExtra()){
                        $paramType = $metadataQuery->getMetadataTypeField($operator->getField());
                }else{
                        $paramType = self::$fieldTypes[$operator->getField()];
                }
                $field = $operator->getField();
                $value = $operator->getValue();
                $type = $operator->getType();

                switch($operator->getExtra()) {
                        case IMetadataQuery::EXTRA:
                                $metadataQuery->joinIndex($field); // join index table if not joined yet
                                $field = $metadataQuery->getMetadataValueField($field);
                                break;
                        default:
                                throw new \InvalidArgumentException('Invalid extra type: ' . $operator->getExtra());
                }

                return [$field, $value, $type, $paramType];
        }
joshtrichards commented 5 months ago

Hi @arquitecturatic - Can submit your suggestions as a PR for review? Thanks!