Normalize file names for tar.gz (#3268)

diff --git a/lib/src/io.dart b/lib/src/io.dart
index 231aba5..d351e2b 100644
--- a/lib/src/io.dart
+++ b/lib/src/io.dart
@@ -966,10 +966,10 @@
   log.fine(buffer.toString());
 
   ArgumentError.checkNotNull(baseDir, 'baseDir');
-  baseDir = path.absolute(baseDir);
+  baseDir = path.normalize(path.absolute(baseDir));
 
   final tarContents = Stream.fromIterable(contents.map((entry) {
-    entry = path.absolute(entry);
+    entry = path.normalize(path.absolute(entry));
     if (!path.isWithin(baseDir, entry)) {
       throw ArgumentError('Entry $entry is not inside $baseDir.');
     }
diff --git a/test/lish/dot_folder_name_test.dart b/test/lish/dot_folder_name_test.dart
new file mode 100644
index 0000000..9f64839
--- /dev/null
+++ b/test/lish/dot_folder_name_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:pub/src/exit_codes.dart' as exit_codes;
+import 'package:test/test.dart';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+
+void main() {
+  test('Can publish files in a .folder', () async {
+    await d.git(appPath).create();
+    await d.validPackage.create();
+    await d.dir(appPath, [
+      d.dir('.vscode', [d.file('a')]),
+      d.file('.pubignore', '!.vscode/')
+    ]).create();
+
+    await runPub(
+      args: ['lish', '--dry-run'],
+      output: contains('''
+|-- .vscode
+|   '-- a'''),
+      exitCode: exit_codes.SUCCESS,
+    );
+  });
+}