do-not-zip icon indicating copy to clipboard operation
do-not-zip copied to clipboard

Fix lack of encoding to UTF-8

Open 7nik opened this issue 3 years ago • 3 comments

Mostly it's PR to fix https://github.com/sveltejs/svelte/issues/3323 I think the issue should be fixed here because this library generates archives with content that doesn't match the one passed to the input.

The first thing is that the library doesn't convert Unicode char codes to UTF-8's. The second is that for surrogate characters, the lib is ignoring the second character of the pair. For both cases, added tests with checking of the unzipped content.

Here are logs of new tests without encoding the input text:

TAP version 13
# Creates a zip file that jszip can read
ok 1 - should be equal
# All the files presented in the archive
ok 2 - should be truthy
ok 3 - should be truthy
ok 4 - should be truthy
ok 5 - should be truthy
# All the contents are the same
ok 6 - should be equal
ok 7 - should be equal
not ok 8 - should be equal
  ---
  expected: "012345"
  actual: "абвгде"
  at: " data.forEach (http://localhost:46487/bundle.js:18833:16)"
  operator: "equal"
  ...
not ok 9 - should be equal
  ---
  expected: "\u0000"
  actual: "𐀀"
  at: " data.forEach (http://localhost:46487/bundle.js:18833:16)"
  operator: "equal"
  ...
# Creates a Blob in the browser
ok 10 - output is a Blob
1..10
# failed 2 of 10 tests

Test 8 checks encoding of characters above 0x7F and the first letters of the Cyrillic alphabet were turned to numbers XD Test 9 checks encoding of surrogate characters (used to display symbols above 0xFFFF) - the sample symbol was turned to \0.

7nik avatar Nov 22 '21 22:11 7nik

Adding a dependency on TextEncoder would add a requirement of Node 12, which isn't necessarily a deal-breaker, and if there isn't a more compatible way of doing this, I think that's a reasonable reason to make a breaking change for this.

I haven't looked closely at the browser support for this API, but it looks like it's "pretty much anything except IE" which, for the purposes of the Svelte REPL, is certainly acceptable.

Conduitry avatar Nov 22 '21 23:11 Conduitry

It's possible to manually encode, e.g. https://gist.github.com/joni/3760795 (though not sure how to be about the license) But I think then it will need more checking that it does all the thing correctly.

7nik avatar Nov 22 '21 23:11 7nik

I've looked for packages for converting string to UTF-8 and stopped on utf8-bytes - it does only what we need, small, has MIT license, and I'm ok with its implementation. Other packages, e.g., utf8, @webassemblyjs/utf8, @aws-sdk/util-utf8-browser, @aws-sdk/util-utf8-node, encode-utf8, to-utf8, use implementation based on string concatination or return a type that doesn't fit here or something else. So I propose to use utf8-bytes if you don't mind.

7nik avatar Nov 27 '21 23:11 7nik