From f615facbbad779456eb09837b0229bc8f2cbe9d2 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Thu, 4 May 2023 12:45:58 +0200 Subject: [PATCH] fix(export): don't fail when trying to write a file name > 255 bytes --- app/lib/download_manager/parallel_download_queue.rb | 13 ++++++++++++- .../parallel_download_queue_spec.rb | 11 +++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/lib/download_manager/parallel_download_queue.rb b/app/lib/download_manager/parallel_download_queue.rb index 5c5d549da..675fb5780 100644 --- a/app/lib/download_manager/parallel_download_queue.rb +++ b/app/lib/download_manager/parallel_download_queue.rb @@ -28,7 +28,7 @@ module DownloadManager # can't be used with typhoeus, otherwise block is closed before the request is run by hydra def download_one(attachment:, path_in_download_dir:, http_client:) - attachment_path = File.join(destination, path_in_download_dir) + attachment_path = File.join(destination, sanitize_filename(path_in_download_dir)) attachment_dir = File.dirname(attachment_path) FileUtils.mkdir_p(attachment_dir) if !Dir.exist?(attachment_dir) # defensive, do not write in undefined dir @@ -49,5 +49,16 @@ module DownloadManager http_client.queue(request) end end + + private + + def sanitize_filename(filename) + return filename if filename.bytesize <= 255 + + ext = File.extname(filename) + basename = File.basename(filename, ext).byteslice(0, 255 - ext.bytesize) + + basename + ext + end end end diff --git a/spec/lib/download_manager/parallel_download_queue_spec.rb b/spec/lib/download_manager/parallel_download_queue_spec.rb index cdc67e820..55fd96ddf 100644 --- a/spec/lib/download_manager/parallel_download_queue_spec.rb +++ b/spec/lib/download_manager/parallel_download_queue_spec.rb @@ -40,5 +40,16 @@ describe DownloadManager::ParallelDownloadQueue do # expect(downloadable_manager.errors).to have_key(destination) end end + + context 'with a destination filename too long' do + let(:destination) { 'a' * 252 + '.txt' } + + it 'limit the file path to 255 bytes' do + target = File.join(download_to_dir, 'a' * 251 + '.txt') + expect { subject }.to change { File.exist?(target) } + attachment.file.rewind + expect(attachment.file.read).to eq(File.read(target)) + end + end end end