From a64b534b05f00c3a68bc7c46cc99f35ac40cdc9a Mon Sep 17 00:00:00 2001 From: sakaguchi Date: Wed, 3 Jun 2026 00:29:11 +0900 Subject: [PATCH] =?UTF-8?q?fix=20#3938=20fgetcsvReg=E3=81=AB=E3=82=88?= =?UTF-8?q?=E3=82=8BCSV=E8=AA=AD=E3=81=BF=E8=BE=BC=E3=81=BF=E6=99=82?= =?UTF-8?q?=E3=81=AB=E6=AD=A3=E5=B8=B8=E3=81=AB=E3=83=87=E3=83=BC=E3=82=BF?= =?UTF-8?q?=E3=82=92=E8=AA=AD=E3=81=BF=E5=8F=96=E3=82=8C=E3=81=AA=E3=81=84?= =?UTF-8?q?=E5=A0=B4=E5=90=88=E3=81=8C=E3=81=82=E3=82=8B=E4=BB=B6=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Service/BcDatabaseService.php | 15 +++++++++----- .../Service/BcDatabaseServiceTest.php | 20 +++++++++++++++++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/plugins/baser-core/src/Service/BcDatabaseService.php b/plugins/baser-core/src/Service/BcDatabaseService.php index 7c95c473b8..3d0316a7b3 100644 --- a/plugins/baser-core/src/Service/BcDatabaseService.php +++ b/plugins/baser-core/src/Service/BcDatabaseService.php @@ -718,13 +718,18 @@ public function loadCsvToArray($path, $encoding = 'auto') return false; } - $head = fgetcsv($fp, 10240); + $head = fgetcsv($fp, null, ',', '"', ''); + if ($head === false || $head === [null] || $head === []) { + fclose($fp); + return []; + } // UTF-8(BOM付)で何故か、配列の最初のキーに""が付加されてしまう - $head[0] = preg_replace('/^(.+)$/', "$1", $head[0]); - $head[0] = preg_replace('/^"(.+)"$/', "$1", $head[0]); - + $head[0] = preg_replace("/^\xEF\xBB\xBF(.+)$/", '$1', (string)$head[0]); + $head[0] = preg_replace('/^"(.+)"$/', "$1", (string)$head[0]); $records = []; - while(($record = BcUtil::fgetcsvReg($fp, 10240)) !== false) { + // length = null(行長制限なし) escape = 空文字(独自エスケープ無効) + while(($record = fgetcsv($fp, null, ',', '"', '')) !== false) { + if ($record === [null] || $record === []) continue; if ($encoding && $appEncoding != $encoding) { mb_convert_variables($appEncoding, $encoding, $record); } diff --git a/plugins/baser-core/tests/TestCase/Service/BcDatabaseServiceTest.php b/plugins/baser-core/tests/TestCase/Service/BcDatabaseServiceTest.php index 47a8183645..aec6bc6c92 100644 --- a/plugins/baser-core/tests/TestCase/Service/BcDatabaseServiceTest.php +++ b/plugins/baser-core/tests/TestCase/Service/BcDatabaseServiceTest.php @@ -348,16 +348,32 @@ public function test_loadCsvToArray() //SJIS のCSVファイルを作成 $options = [ 'path' => $path, - 'encoding' => 'sjis', + 'encoding' => 'SJIS-win', 'init' => false, ]; $this->BcDatabaseService->writeCsv('contents', $options); - $rs = $this->BcDatabaseService->loadCsvToArray($path); + $rs = $this->BcDatabaseService->loadCsvToArray($path, 'SJIS-win'); $this->assertIsArray($rs); // 戻り値の配列の値のエンコードがUTF-8になっている事を確認 $this->assertEquals('メインサイト', $rs[0]['title']); $this->assertTrue(mb_check_encoding($rs[0]['title'], 'UTF-8')); + // SJISのCSVで「能」や埋め込み引用符を含んでも正しくUTF-8へ変換できることを確認 + $csvContent = "\"a\",\"i\",\"u\",\"e\"\n"; + $csvContent .= "\"あ\",\"い\",\"う\",\"能\"\"能\"\n"; + file_put_contents($path, mb_convert_encoding($csvContent, 'SJIS-win', 'UTF-8')); + $rs = $this->BcDatabaseService->loadCsvToArray($path, 'SJIS-win'); + $this->assertEquals('能"能', $rs[0]['e']); + $this->assertTrue(mb_check_encoding($rs[0]['e'], 'UTF-8')); + + // 長大な引用符を含む値でも、列が欠落せずに読み込めることを確認 + $csvContent = "\"a\",\"i\",\"u\",\"e\"\n"; + $csvContent .= "\"あ\",\"い\",\"う\",\"" . str_repeat('""', 13000) . "\"\n"; + file_put_contents($path, $csvContent); + $rs = $this->BcDatabaseService->loadCsvToArray($path, 'UTF-8'); + $this->assertCount(4, $rs[0]); + $this->assertEquals(13000, strlen($rs[0]['e'])); + $file = new BcFile($path); $file->delete(); }