From 7007ad90cec94461146d8dcf5fe5e79db0fa5769 Mon Sep 17 00:00:00 2001
From: xuty <xty50337@hotmail.com>
Date: Mon, 10 Jan 2022 23:56:43 +0800
Subject: [PATCH] Fix listObject with utf-8 prefix

---
 lib/src/minio_helpers.dart | 26 +--------------------
 test/minio_test.dart       | 47 +++++++++++++++++++++++++++++++++-----
 2 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/lib/src/minio_helpers.dart b/lib/src/minio_helpers.dart
index 2f5f4fd..ba1bf3a 100644
--- a/lib/src/minio_helpers.dart
+++ b/lib/src/minio_helpers.dart
@@ -272,31 +272,7 @@ String encodePath(Uri uri) {
   return result.toString();
 }
 
-final _queryIgnoredChars = {
-  '-'.codeUnitAt(0),
-  '_'.codeUnitAt(0),
-  '.'.codeUnitAt(0),
-  '~'.codeUnitAt(0),
-};
-
 /// encode [uri].path to HTML hex escape sequence
 String encodeCanonicalQuery(String query) {
-  final result = StringBuffer();
-  for (var char in query.codeUnits) {
-    if (_A <= char && char <= _Z ||
-        _a <= char && char <= _z ||
-        _0 <= char && char <= _9) {
-      result.writeCharCode(char);
-      continue;
-    }
-
-    if (_queryIgnoredChars.contains(char)) {
-      result.writeCharCode(char);
-      continue;
-    }
-
-    result.write('%');
-    result.write(hex.encode([char]).toUpperCase());
-  }
-  return result.toString();
+  return Uri.encodeQueryComponent(query).replaceAll('+', '%20');
 }
diff --git a/test/minio_test.dart b/test/minio_test.dart
index 2104e21..5913f26 100644
--- a/test/minio_test.dart
+++ b/test/minio_test.dart
@@ -323,21 +323,32 @@ void testGetObject() {
   group('getObject()', () {
     final minio = getMinioClient();
     final bucketName = uniqueName();
-    final objectName = uniqueName();
+    final object = uniqueName();
+    final objectUtf8 = uniqueName() + '/銇傘倠銇ㄣ亾銈�/鏌愪釜鏂囦欢.馃';
     final objectData = Uint8List.fromList([1, 2, 3]);
 
     setUpAll(() async {
       await minio.makeBucket(bucketName);
-      await minio.putObject(bucketName, objectName, Stream.value(objectData));
+      await minio.putObject(bucketName, object, Stream.value(objectData));
+      await minio.putObject(bucketName, objectUtf8, Stream.value(objectData));
     });
 
     tearDownAll(() async {
-      await minio.removeObject(bucketName, objectName);
+      await minio.removeObject(bucketName, object);
+      await minio.removeObject(bucketName, objectUtf8);
       await minio.removeBucket(bucketName);
     });
 
     test('succeeds', () async {
-      final stream = await minio.getObject(bucketName, objectName);
+      final stream = await minio.getObject(bucketName, object);
+      final buffer = BytesBuilder();
+      await stream.forEach((data) => buffer.add(data));
+      expect(stream.contentLength, equals(objectData.length));
+      expect(buffer.takeBytes(), equals(objectData));
+    });
+
+    test('succeeds with utf8 object name', () async {
+      final stream = await minio.getObject(bucketName, object);
       final buffer = BytesBuilder();
       await stream.forEach((data) => buffer.add(data));
       expect(stream.contentLength, equals(objectData.length));
@@ -346,14 +357,14 @@ void testGetObject() {
 
     test('fails on invalid bucket', () {
       expect(
-        () async => await minio.getObject('$bucketName-invalid', objectName),
+        () async => await minio.getObject('$bucketName-invalid', object),
         throwsA(isA<MinioError>()),
       );
     });
 
     test('fails on invalid object', () {
       expect(
-        () async => await minio.getObject(bucketName, '$objectName-invalid'),
+        () async => await minio.getObject(bucketName, '$object-invalid'),
         throwsA(isA<MinioError>()),
       );
     });
@@ -701,6 +712,7 @@ void testListObjects() {
 
     test('succeeds', () async {
       final result = await minio.listAllObjects(bucketName);
+      print(result);
       expect(result.objects.map((e) => e.key).contains(objectName), isTrue);
       expect(result.objects.map((e) => e.key).contains(objectNameUtf8), isTrue);
     });
@@ -731,6 +743,29 @@ void testListObjects() {
 
     test('succeeds', () async {
       final result = await minio.listAllObjects(bucket, prefix: 'new  folder/');
+      expect(result.objects.map((e) => e.key).contains(object), isTrue);
+    });
+  });
+
+  group('listAllObjects() works when prefix contains utf-8 characters', () {
+    final minio = getMinioClient();
+    final bucket = uniqueName();
+    final prefix = '馃崕馃尠馃崒馃崜/鏂囦欢澶�1/';
+    final object = '${prefix}new file.txt';
+    final data = Uint8List.fromList([1, 2, 3, 4, 5]);
+
+    setUpAll(() async {
+      await minio.makeBucket(bucket);
+      await minio.putObject(bucket, object, Stream.value(data));
+    });
+
+    tearDownAll(() async {
+      await minio.removeObject(bucket, object);
+      await minio.removeBucket(bucket);
+    });
+
+    test('succeeds', () async {
+      final result = await minio.listAllObjects(bucket, prefix: prefix);
       print(result);
       expect(result.objects.map((e) => e.key).contains(object), isTrue);
     });
-- 
GitLab