IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Java Discussion :

Patch probleme java.util.zip


Sujet :

Contribuez Java

Mode arborescent

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Par défaut Patch probleme java.util.zip
    Bonjour,

    Le package java.util.zip génère une exception lors de la décompression de fichiers dont le nom comporte des caractères non UTF-8.

    La résolution de ce bug est vivement souhaitée par les développeurs des 4 coins du monde, d'où sa présence à la 2ème place du top 25 des bugs JAVA:

    http://bugs.sun.com/bugdatabase/top25_bugs.do

    De plus, lors de la compression, le nom des entrées est mal converti pour les mêmes raisons.

    Je propose de corriger ce bug ici et de l'envoyer à SUN pour l'inclure dans une prochaine release. (why not)


    J'ai commencé à y jetter un coup d'oeil pour la décompression, et j'arrive à décompresser des fichiers ZIP avec des caractères accentués sans générer d'exception.


    Vous trouverez l'ensemble des classes en PJ:
    - Le ZipInputStream qui pose problème et qui a subit quelques modifs de ma part.
    - ZipConstant n'a pas changé mais comme les constantes ne sont pas publiques, alors il a été nécessaire de le copier dans le package.
    - ZipUtils, ma classe utilitaire ZIP, exploitable, mais pas dans sa version finale.


    Utilisation: disposer de documents avec des accents ou autres caractères mal gérés dans le répertoire test, créés à la racine du projet ; les zipper avec Winzip (nom=fromWinzip.zip), Winrar (nom=fromWinrar.zip).

    Exemple d'utilisation dans un petit test.java contenant un petit main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public static void main(String[] args) {
    	String path = "test/";
     
    	try {
    		ZipUtils.compress(path, new File(path+"fromJAVAZIP.zip"));
     
    		ZipUtils.decompress(new File(path + "fromWinzip.zip"), path + "/unzippedWINZIP");
    		//ZipUtils.decompress(new File(path + "fromWInrar.zip"), path + "/unzippedWINRAR");
    		//ZipUtils.decompress(new File(path + "fromJAVAZIP.zip"), path + "/unzippedJAVAZIP");
     
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }


    Pour ceux qui sont vraiment experts, et qui peuvent se passer de ce genre de tests, voici là où le problème se pose:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    	/**
             * Fetches a UTF8-encoded String from the specified byte array.
             */
    	private static String getUTF8String(byte[] b, int off, int len) {
    		// First, count the number of characters in the sequence
    		int count = 0;
    		int max = off + len;
    		int i = off;
    		while (i < max) {
    			int c = b[i++] & 0xff;
    			switch (c >> 4) {
    			case 0:
    			case 1:
    			case 2:
    			case 3:
    			case 4:
    			case 5:
    			case 6:
    			case 7:
    				// 0xxxxxxx
    				count++;
    				break;
    			case 12:
    			case 13:
    				// 110xxxxx 10xxxxxx
    				if ((int) (b[i++] & 0xc0) != 0x80) {
    					throw new IllegalArgumentException();
    				}
    				count++;
    				break;
    			case 14:
    				// 1110xxxx 10xxxxxx 10xxxxxx
    				if (((int) (b[i++] & 0xc0) != 0x80)
    						|| ((int) (b[i++] & 0xc0) != 0x80)) {
    					throw new IllegalArgumentException();
    				}
    				count++;
    				break;
    			default:
    				// 10xxxxxx, 1111xxxx
    				throw new IllegalArgumentException();
    			}
    		}
    		if (i != max) {
    			throw new IllegalArgumentException();
    		}
    		// Now decode the characters...
    		char[] cs = new char[count];
    		i = 0;
    		while (off < max) {
    			int c = b[off++] & 0xff;
    			switch (c >> 4) {
    			case 0:
    			case 1:
    			case 2:
    			case 3:
    			case 4:
    			case 5:
    			case 6:
    			case 7:
    				// 0xxxxxxx
    				cs[i++] = (char) c;
    				break;
    			case 12:
    			case 13:
    				// 110xxxxx 10xxxxxx
    				cs[i++] = (char) (((c & 0x1f) << 6) | (b[off++] & 0x3f));
    				break;
    			case 14:
    				// 1110xxxx 10xxxxxx 10xxxxxx
    				int t = (b[off++] & 0x3f) << 6;
    				cs[i++] = (char) (((c & 0x0f) << 12) | t | (b[off++] & 0x3f));
    				break;
    			default:
    				// 10xxxxxx, 1111xxxx
    				throw new IllegalArgumentException();
    			}
    		}
     
    		return new String(cs, 0, count);
    	}
     
    	private String getZipEntryName(byte[] b, int off, int len) {
    		String result = null;
     
    		try {
    			result = new String(b, off, len, "UTF-8");
    		} catch (UnsupportedEncodingException e) {
    			result = new String(b, off, len);
    		}
     
    		return result;
    	}
    Dans la version originale, l'appel se fait avec getUTF8String et le plantage se situe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    			default:
    				// 10xxxxxx, 1111xxxx
    				throw new IllegalArgumentException();

    Ma solution a consisté pour le moment à bifurquer l'appel vers getZipEntryName.

    Mais je bloque, d'où la demande de la contribution de personnes plus confirmées que moi.


    Cordialement,


    Billy


    EDIT: SystemUtils est une autre classe non incluse en PJ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FILE_SEPARATOR = System.getProperty("file.separator");
    FILE_ENCODING = System.getProperty("file.encoding");
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. probleme avec java.util.zip
    Par tarekphp dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 13/05/2009, 18h36
  2. Java.util.zip : decompresser un fichier zip
    Par kam81 dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 22/07/2007, 12h45
  3. problème avec java.util.zip.Inflater
    Par felix79 dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 11/06/2007, 15h02
  4. Importer java.utils.zip ?
    Par Chii-san dans le forum Java ME
    Réponses: 3
    Dernier message: 15/03/2007, 15h01
  5. [C#] #ziplib ou J# (java.util.zip) pour ZIPper?
    Par SErhio dans le forum Windows Forms
    Réponses: 10
    Dernier message: 11/02/2005, 15h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo