Skip to content

Commit

Permalink
zip: add support multibyte path
Browse files Browse the repository at this point in the history
  • Loading branch information
kou committed Feb 28, 2019
1 parent a8db367 commit 4605b33
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 3 deletions.
30 changes: 28 additions & 2 deletions lib/chupa-text/decomposers/zip.rb
@@ -1,4 +1,4 @@
# Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
# Copyright (C) 2017-2019 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -45,14 +45,40 @@ def decompose(data)
end
entry_uri = data.uri.dup
base_path = entry_uri.path.gsub(/\.zip\z/i, "")
entry_uri.path = "#{base_path}/#{entry.zip_path}"
path = convert_path_encoding(entry.zip_path, base_path.encoding)
entry_uri.path = "#{base_path}/#{convert_to_uri_path(path)}"
entry_data = VirtualFileData.new(entry_uri,
entry.file_data,
source_data: data)
yield(entry_data)
end
end
end

private
def convert_path_encoding(path, encoding)
return path if path.ascii_only?

candidates = [
Encoding::UTF_8,
Encoding::Windows_31J,
]
candidates.each do |candidate|
path.force_encoding(candidate)
return path.encode(encoding) if path.valid_encoding?
end
path.encode(encoding,
Encoding::UTF_8,
invalid: :replace,
undef: :replace)
end

def convert_to_uri_path(path)
converted_components = path.split("/").collect do |component|
CGI.escape(component)
end
converted_components.join("/")
end
end
end
end
32 changes: 31 additions & 1 deletion test/decomposers/test-zip.rb
@@ -1,4 +1,4 @@
# Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
# Copyright (C) 2017-2019 Kouhei Sutou <kou@clear-code.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -63,6 +63,36 @@ def decompose(data_path)
decompose(data_path))
end

sub_test_case("multibyte") do
test("cp932") do
data_path = Pathname.new(fixture_path("cp932.zip"))
base_path = data_path.sub_ext("")
path = CGI.escape("こんにちは.txt")
assert_equal([
{
:uri => file_uri("#{base_path}/cp932/#{path}").to_s,
:body => "こんにちは\n".encode("cp932").b,
:source => file_uri(data_path).to_s,
},
],
decompose(data_path))
end

test("UTF-8") do
data_path = Pathname.new(fixture_path("utf-8.zip"))
base_path = data_path.sub_ext("")
path = CGI.escape("こんにちは.txt")
assert_equal([
{
:uri => file_uri("#{base_path}/utf-8/#{path}").to_s,
:body => "こんにちは\n".b,
:source => file_uri(data_path).to_s,
},
],
decompose(data_path))
end
end

sub_test_case("encrypted") do
test("without password") do
data_path = Pathname.new(fixture_path("password.zip"))
Expand Down
Binary file added test/fixture/zip/cp932.zip
Binary file not shown.
Binary file added test/fixture/zip/utf-8.zip
Binary file not shown.

0 comments on commit 4605b33

Please sign in to comment.