Contacts import aborts with TypeError when vCards have no UID (TextImporter structure)
维护者通常 1 天内回复
@SebastianKrupinski 已经在做这个了。
开始于 2026年11月10日。
评估
调研方向
从 apps/dav/lib/CardDAV/Import/TextImporter.php 中的 analyze() 开始,这里没有 UID 的组件被存储为裸实例而不是列表。然后检查第 75 行附近的 ImportService::importText(),它读取 $instances[0]。修复方法是将没有 UID 的条目包装进列表,并且需要在 apps/dav/lib/CalDAV/Import/TextImporter.php 中检查同样的模式。当一张没有 UID 的 vCard 能成功导入时完成,并通过 apps/dav 导入测试中的一个测试来验证。
由索引模型根据 Issue 内容生成。
描述
Bug description
Importing a .vcf file in the Contacts app ("Import contacts") fails completely ("0 of 629 imported") when the vCards have no UID property. A Google Contacts export is the typical case: none of its 629 cards had a UID.
The server log shows:
TypeError: OCA\DAV\CardDAV\Import\TextImporter::extract(): Argument #1 ($start) must be of type int, string given,
called in apps/dav/lib/CardDAV/Import/ImportService.php on line 75
(request: /ocs/v2.php/contacts/import)
Cause
In apps/dav/lib/CardDAV/Import/TextImporter.php::analyze(), a component with a UID is stored as a list of instances:
$this->structure[$componentType][$componentId][] = [$componentType, $componentId, $componentStart, $componentEnd];
A component without a UID is stored as a bare instance, not wrapped in a list:
$this->structure[$componentType][] = [$componentType, $componentId, $componentStart, $componentEnd];
ImportService::importText() expects a list of instances in both cases:
foreach ($structure['VCARD'] as $cid => $instances) {
$instance = $instances[0]; // "VCARD" (string) for UID-less cards
$sObjectContents = $importer->extract($instance[2], $instance[3]); // "A", "R" -> TypeError
The generator throws on the first UID-less card, so the whole import is aborted.
The same pattern exists in apps/dav/lib/CalDAV/Import/TextImporter.php. There, ImportService casts the values with (int), so it does not throw, but it would read wrong byte ranges.
Steps to reproduce
- Create
test.vcf:BEGIN:VCARD VERSION:3.0 FN:Erika Mustermann N:Mustermann;Erika;;; TEL;TYPE=CELL:+49 170 0000000 END:VCARD - Contacts → Contacts settings → Import contacts → choose
test.vcf. - Result: "0 of 1 imported", with the TypeError above in
nextcloud.log.
Adding a UID: line to each card makes the import succeed. I verified this with the original file: all 629 cards imported.
Expected behavior
vCards without a UID are imported. A UID is optional in vCard 3.0, and the CardDAV backend can generate one.
Suggested fix
Wrap the UID-less entry in a list as well, for example:
$this->structure[$componentType][] = [[$componentType, $componentId, $componentStart, $componentEnd]];
The same applies to the CalDAV TextImporter.
Versions
- Nextcloud 35.0.2 (Docker image
nextcloud:35-apache), PHP 8.5.12, MariaDB 11.4 - Contacts app 8.9.5
- The same code is in
master,stable35andstable34as of today.
- 主要语言
- PHP
- 星标
- 37.5k
- 派生
- 5.4k
- 平均合并
- 1 天 14 小时
- 30 天内合并 PR
- 648
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
nextcloud/server 的其他 Issue
-
0. Needs triage 35-feedback bug
难度 2/5 1-3 小时 新手友好度 66/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 62/100
维护者通常 1 天内回复
-
Unified search: screen reader hears "No matching results" on mobile even when there are results可能已有人在做 @lazerg 于 8 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
34-feedback needs info
难度 2/5 1-3 小时 新手友好度 77/100
nextcloud/server#66249 · 3 条评论 ·
维护者通常 1 天内回复
-
[Bug]: DAV Forbidden/InvalidPath responses break on "&" in the message (DOMDocument::createElementNS(): unterminated entity reference)可能已有人在做 @th-joerger 于 12 天前认领。 未关闭0. Needs triage 35-feedback bug
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
相似的 Issue
-
bug
难度 1/5 1 小时以内 新手友好度 72/100
wpgenius/stackfolio#22 ·
-
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 74/100
维护者通常 1 天内回复