1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tools.build.apkzlib.zip; 18 19 import java.io.IOException; 20 import javax.annotation.Nonnull; 21 22 /** 23 * General purpose bit flags. Contains the encoding of the zip's general purpose bits. 24 * 25 * <p>We don't really care about the method bit(s). These are bits 1 and 2. Here are the values: 26 * <ul> 27 * <li>0 (00): Normal (-en) compression option was used. 28 * <li>1 (01): Maximum (-exx/-ex) compression option was used. 29 * <li>2 (10): Fast (-ef) compression option was used. 30 * <li>3 (11): Super Fast (-es) compression option was used. 31 * </ul> 32 */ 33 class GPFlags { 34 35 /** 36 * Is the entry encrypted? 37 */ 38 private static final int BIT_ENCRYPTION = 1; 39 40 /** 41 * Has CRC computation been deferred and, therefore, does a data description block exist? 42 */ 43 private static final int BIT_DEFERRED_CRC = (1 << 3); 44 45 /** 46 * Is enhanced deflating used? 47 */ 48 private static final int BIT_ENHANCED_DEFLATING = (1 << 4); 49 50 /** 51 * Does the entry contain patched data? 52 */ 53 private static final int BIT_PATCHED_DATA = (1 << 5); 54 55 /** 56 * Is strong encryption used? 57 */ 58 private static final int BIT_STRONG_ENCRYPTION = (1 << 6) | (1 << 13); 59 60 /** 61 * If this bit is set the filename and comment fields for this file must be encoded using UTF-8. 62 */ 63 private static final int BIT_EFS = (1 << 11); 64 65 /** 66 * Unused bits. 67 */ 68 private static final int BIT_UNUSED = (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) 69 | (1 << 14) | (1 << 15); 70 71 /** 72 * Bit flag value. 73 */ 74 private final long value; 75 76 /** 77 * Has the CRC computation beeen deferred? 78 */ 79 private boolean deferredCrc; 80 81 /** 82 * Is the file name encoded in UTF-8? 83 */ 84 private boolean utf8FileName; 85 86 /** 87 * Creates a new flags object. 88 * 89 * @param value the value of the bit mask 90 */ GPFlags(long value)91 private GPFlags(long value) { 92 this.value = value; 93 94 deferredCrc = ((value & BIT_DEFERRED_CRC) != 0); 95 utf8FileName = ((value & BIT_EFS) != 0); 96 } 97 98 /** 99 * Obtains the flags value. 100 * 101 * @return the value of the bit mask 102 */ getValue()103 public long getValue() { 104 return value; 105 } 106 107 /** 108 * Is the CRC computation deferred? 109 * 110 * @return is the CRC computation deferred? 111 */ isDeferredCrc()112 public boolean isDeferredCrc() { 113 return deferredCrc; 114 } 115 116 /** 117 * Is the file name encoded in UTF-8? 118 * 119 * @return is the file name encoded in UTF-8? 120 */ isUtf8FileName()121 public boolean isUtf8FileName() { 122 return utf8FileName; 123 } 124 125 /** 126 * Creates a new bit mask. 127 * 128 * @param utf8Encoding should UTF-8 encoding be used? 129 * @return the new bit mask 130 */ 131 @Nonnull make(boolean utf8Encoding)132 static GPFlags make(boolean utf8Encoding) { 133 long flags = 0; 134 135 if (utf8Encoding) { 136 flags |= BIT_EFS; 137 } 138 139 return new GPFlags(flags); 140 } 141 142 /** 143 * Creates the flag information from a byte. This method will also validate that only 144 * supported options are defined in the flag. 145 * 146 * @param bits the bit mask 147 * @return the created flag information 148 * @throws IOException unsupported options are used in the bit mask 149 */ 150 @Nonnull from(long bits)151 static GPFlags from(long bits) throws IOException { 152 if ((bits & BIT_ENCRYPTION) != 0) { 153 throw new IOException("Zip files with encrypted of entries not supported."); 154 } 155 156 if ((bits & BIT_ENHANCED_DEFLATING) != 0) { 157 throw new IOException("Enhanced deflating not supported."); 158 } 159 160 if ((bits & BIT_PATCHED_DATA) != 0) { 161 throw new IOException("Compressed patched data not supported."); 162 } 163 164 if ((bits & BIT_STRONG_ENCRYPTION) != 0) { 165 throw new IOException("Strong encryption not supported."); 166 } 167 168 if ((bits & BIT_UNUSED) != 0) { 169 throw new IOException("Unused bits set in directory entry. Weird. I don't know what's " 170 + "going on."); 171 } 172 173 if ((bits & 0xffffffff00000000L) != 0) { 174 throw new IOException("Unsupported bits after 32."); 175 } 176 177 return new GPFlags(bits); 178 } 179 } 180