{"action":"created","issue":{"url":"https://api.github.com/repos/gildas-lormeau/zip.js/issues/126","labels_url":"https://api.github.com/repos/gildas-lormeau/zip.js/issues/126/labels{/name}","comments_url":"https://api.github.com/repos/gildas-lormeau/zip.js/issues/126/comments","events_url":"https://api.github.com/repos/gildas-lormeau/zip.js/issues/126/events","html_url":"https://github.com/gildas-lormeau/zip.js/issues/126","id":76480488,"number":126,"title":"File already exists.","user":{"login":"plaastik","id":11281785,"avatar_url":"https://avatars.githubusercontent.com/u/11281785?v=3","gravatar_id":"","url":"https://api.github.com/users/plaastik","html_url":"https://github.com/plaastik","followers_url":"https://api.github.com/users/plaastik/followers","following_url":"https://api.github.com/users/plaastik/following{/other_user}","gists_url":"https://api.github.com/users/plaastik/gists{/gist_id}","starred_url":"https://api.github.com/users/plaastik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plaastik/subscriptions","organizations_url":"https://api.github.com/users/plaastik/orgs","repos_url":"https://api.github.com/users/plaastik/repos","events_url":"https://api.github.com/users/plaastik/events{/privacy}","received_events_url":"https://api.github.com/users/plaastik/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-05-14T20:30:12Z","updated_at":"2015-05-14T21:10:18Z","closed_at":null,"body":"I have an app that I am making for Chrome OS that uses your zip library which produces the error titled above.\r\n\r\nThe error occurs after creating, and every time closing after, several zip files with BlobReader. IT happens in this section of code :\r\n\r\nfunction BlobReader(blob) {\r\n\t\tvar that = this;\r\n\r\n\t\tfunction init(callback) {\r\n\t\t\tthat.size = blob.size;\r\n\t\t\t// Here, line 174 of zip.js\r\n                        callback();\r\n\t\t}"},"comment":{"url":"https://api.github.com/repos/gildas-lormeau/zip.js/issues/comments/102170311","html_url":"https://github.com/gildas-lormeau/zip.js/issues/126#issuecomment-102170311","issue_url":"https://api.github.com/repos/gildas-lormeau/zip.js/issues/126","id":102170311,"user":{"login":"plaastik","id":11281785,"avatar_url":"https://avatars.githubusercontent.com/u/11281785?v=3","gravatar_id":"","url":"https://api.github.com/users/plaastik","html_url":"https://github.com/plaastik","followers_url":"https://api.github.com/users/plaastik/followers","following_url":"https://api.github.com/users/plaastik/following{/other_user}","gists_url":"https://api.github.com/users/plaastik/gists{/gist_id}","starred_url":"https://api.github.com/users/plaastik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/plaastik/subscriptions","organizations_url":"https://api.github.com/users/plaastik/orgs","repos_url":"https://api.github.com/users/plaastik/repos","events_url":"https://api.github.com/users/plaastik/events{/privacy}","received_events_url":"https://api.github.com/users/plaastik/received_events","type":"User","site_admin":false},"created_at":"2015-05-14T21:10:18Z","updated_at":"2015-05-14T21:10:18Z","body":"\r\nIt ain't pretty yet, but here it is ...\r\n\r\n\r\nzip.useWebWorkers = true;\r\nzip.workerScriptsPath = \"../assets/libs/zip/\";\r\n\r\nvar fs = null;\r\nvar akryptikaApp = angular.module('akryptikaApp', []);\r\n\r\nakryptikaApp.controller('MainController', ['$scope', MainController]);\r\n\r\nfunction MainController($scope) {\r\n    var contentHash = null;\r\n    var currentContentHash = null;\r\n    var contentProcessingDate = null;\r\n    var cryptoAlgo = 0;\r\n    var cryptoKey = null;\r\n    var currentlyProcessing = false;\r\n    var cryptoKeyType = 0;\r\n    var fileKey = null;\r\n    var encryptedContent = null;\r\n    var decryptedContent = null;\r\n    var signature = null;\r\n    var fileContent = null;\r\n    var encryptButton = document.getElementById('encrypt_btn');\r\n    var decryptButton = document.getElementById('decrypt_btn');\r\n    var selectedAction = 0;\r\n    var filename = 'encrypted_file';\r\n    var zipModel = (function() {\r\n        var zipFileEntry, zipWriter, writer, creationMethod, URL = window.URL || window.webkitURL;\r\n\r\n        return {\r\n            addFiles: function addFiles(files, oninit, onadd, onprogress, onend) {\r\n                var addIndex = 0;\r\n\r\n                function nextFile() {\r\n                    var file = files[addIndex];\r\n                    onadd(file);\r\n                    \r\n                    zipWriter.add(file.name, new zip.BlobReader(file), function() {\r\n                        addIndex++;\r\n                        if (addIndex < files.length) {\r\n                            nextFile();\r\n                        } else {\r\n                            onend();\r\n                        }\r\n                    }, onprogress);\r\n                }\r\n\r\n                function createZipWriter() {\r\n                    zip.createWriter(writer, function(writer) {\r\n                        zipWriter = writer;\r\n                        oninit();\r\n                        nextFile();\r\n                    }, onerror);\r\n                }\r\n                if (zipWriter) nextFile();\r\n                else if (creationMethod == \"Blob\") {\r\n                    writer = new zip.BlobWriter();\r\n                    createZipWriter();\r\n                }\r\n                else {\r\n                    createTempFile(function(fileEntry) {\r\n                        zipFileEntry = fileEntry;\r\n                        writer = new zip.FileWriter(zipFileEntry);\r\n                        createZipWriter();\r\n                    });\r\n                }\r\n            },\r\n            getFileURL: function(callback) {\r\n                zipWriter.close(function(file) {\r\n                    if(selectedAction === 0) {\r\n                        encryptContent(file);\r\n                    } else {\r\n                        decryptContent(file);\r\n                    }\r\n                });\r\n            },\r\n            getFile: function(callback) {\r\n                zipWriter.close(callback);\r\n            }\r\n        };\r\n    })();\r\n    \r\n    function clearBuffers() {\r\n        var contentHash = null;\r\n        var contentProcessingDate = null;\r\n        var cryptoAlgo = 0;\r\n        var cryptoKey = null;\r\n        var currentlyProcessing = false;\r\n        var cryptoKeyType = 0;\r\n        var fileKey = null;\r\n        var encryptedContent = null;\r\n        var decryptedContent = null;\r\n        var signature = null;\r\n        var fileContent = null;\r\n        document.getElementById('encrypt_btn').removeAttribute('download');\r\n        document.getElementById('decrypt_btn').removeAttribute('download');\r\n        document.getElementById('encrypt_btn').removeAttribute('href');\r\n        document.getElementById('decrypt_btn').removeAttribute('href');\r\n        document.getElementById('detected_encryption').innerHTML = \"\";\r\n        document.getElementById('passphrase_0').value = \"\";\r\n        document.getElementById('digits_0').value = \"\";\r\n        document.getElementById('passphrase_1').value = \"\";\r\n        document.getElementById('digits_1').value = \"\";\r\n    }\r\n    \r\n    function clearBuffersAfter() {\r\n        document.getElementById('files').value = \"\";\r\n        document.getElementById('choose_2').value = \"\";\r\n        document.getElementById('choose_1_1').value = \"\";\r\n        document.getElementById('choose_2_1').value = \"\";\r\n        document.getElementById('choose_3').value = \"\";\r\n        document.getElementById('selected_0').innerHTML = \"\";\r\n        document.getElementById('selected_1').innerHTML = \"\";\r\n        document.getElementById('selected_2').innerHTML = \"\";\r\n        document.getElementById('selected_3').innerHTML = \"\";\r\n    }\r\n    \r\n    function displayProgress() {\r\n        document.getElementById('progress').style.display = \"block\";\r\n    }\r\n    \r\n    function hideProgress() {\r\n        document.getElementById('progress').style.display = \"none\";\r\n    }\r\n\r\n    function onerror(message) {\r\n        console.log(message);\r\n    }\r\n\r\n    function createTempFile(callback) {\r\n        var digits = Math.random() * 1000 + 5;\r\n        var tmpFilename = \"tmp\" + digits.toString() + \".zip\";\r\n        console.log('tmpFilename :: ' + tmpFilename);\r\n        window.webkitRequestFileSystem(TEMPORARY, 4 * 1024 * 1024 * 1024, function(filesystem) {\r\n            function create() {\r\n                filesystem.root.getFile(tmpFilename, {\r\n                    create: true\r\n                }, function(zipFile) {\r\n                    callback(zipFile);\r\n                });\r\n            }\r\n            filesystem.root.getFile(tmpFilename, null, function(entry) {\r\n                entry.remove(create, create);\r\n            }, create);\r\n        });\r\n    }\r\n\r\n    function createSignature() {\r\n        signature = cryptoAlgo + '^|^|^' + cryptoKeyType + '^|^|^' + contentProcessingDate  + '^|^|^' + contentHash;\r\n    }\r\n\r\n    function encryptContent(file) {\r\n        fileContent = file.slice();\r\n        contentHash = CryptoJS.SHA3(CryptoJS.lib.WordArray.create(new Uint8Array(fileContent))).toString();\r\n                    \r\n        switch (cryptoKeyType) {\r\n        case 0:\r\n            cryptoKey = document.getElementById('passphrase_0').value;\r\n            break;\r\n        case 1:\r\n            cryptoKey = fileKey;\r\n            break;\r\n        case 2:\r\n            cryptoKey = document.getElementById('digits_0').value;\r\n            break;\r\n        }\r\n\r\n        var advOptions = null;\r\n        var reader = new FileReader();\r\n        var textContent = \"\";\r\n\r\n        reader.onloadend = function() {\r\n            textContent = reader.result;\r\n            switch (cryptoAlgo) {\r\n            case 0:\r\n                encryptedContent = CryptoJS.AES.encrypt(textContent, cryptoKey);\r\n                break;\r\n            case 1:\r\n                advOptions = document.getElementById('des_options').value;\r\n\r\n                if (advOptions === '1') {\r\n                    encryptedContent = CryptoJS.TripleDES.encrypt(textContent, cryptoKey);\r\n                    break;\r\n                }\r\n\r\n                encryptedContent = CryptoJS.DES.encrypt(textContent, cryptoKey);\r\n                break;\r\n            case 2:\r\n                encryptedContent = CryptoJS.Rabbit.encrypt(textContent, cryptoKey);\r\n                break;\r\n            case 3:\r\n                advOptions = document.getElementById('rc4_options').value;\r\n\r\n                if (advOptions === '1') {\r\n                    encryptedContent = CryptoJS.RC4Drop.encrypt(textContent, cryptoKey);\r\n                    break;\r\n                }\r\n\r\n                encryptedContent = CryptoJS.RC4.encrypt(textContent, cryptoKey);\r\n                break;\r\n            }\r\n            currentlyProcessing = false;\r\n\r\n            contentProcessingDate = Date.now();\r\n\r\n            createSignature();\r\n\r\n            var strContent = encryptedContent.ciphertext.toString() + '31337' + signature;\r\n            var blobImage = new Blob([strContent], {\r\n                type: 'plain/text'\r\n            });\r\n            \r\n            var fileURL = URL.createObjectURL(blobImage);\r\n            \r\n            var clickEvent;\r\n            clickEvent = document.createEvent(\"MouseEvent\");\r\n            clickEvent.initMouseEvent(\"click\", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\r\n            encryptButton.href = fileURL;\r\n            encryptButton.download = filename + '.akry';\r\n            encryptButton.dispatchEvent(clickEvent);\r\n            hideProgress();\r\n            clearBuffersAfter();\r\n        };\r\n        currentlyProcessing = true;\r\n        reader.readAsText(fileContent);\r\n    }\r\n\r\n    function decryptContent(file) {\r\n        switch (cryptoKeyType) {\r\n        case 0:\r\n            cryptoKey = document.getElementById('passphrase_1').value;\r\n            break;\r\n        case 1:\r\n            cryptoKey = fileKey;\r\n            break;\r\n        case 2:\r\n            cryptoKey = document.getElementById('digits_1').value;\r\n            break;\r\n        }\r\n\r\n        var advOptions = null;\r\n        var reader = new FileReader();\r\n        var textContent = \"\";\r\n        \r\n        reader.onloadend = function() {\r\n            textContent = reader.result;\r\n            switch (cryptoAlgo) {\r\n            case 0:\r\n                decryptedContent = CryptoJS.AES.decrypt(textContent, cryptoKey);\r\n                break;\r\n            case 1:\r\n                advOptions = document.getElementById('des_options').value;\r\n\r\n                if (advOptions === '1') {\r\n                    decryptedContent = CryptoJS.TripleDES.decrypt(textContent, cryptoKey);\r\n                    break;\r\n                }\r\n\r\n                decryptedContent = CryptoJS.DES.decrypt(textContent, cryptoKey);\r\n                break;\r\n            case 2:\r\n                decryptedContent = CryptoJS.Rabbit.decrypt(textContent, cryptoKey);\r\n                break;\r\n            case 3:\r\n                advOptions = document.getElementById('rc4_options').value;\r\n\r\n                if (advOptions === '1') {\r\n                    decryptedContent = CryptoJS.RC4Drop.decrypt(textContent, cryptoKey);\r\n                    break;\r\n                }\r\n\r\n                decryptedContent = CryptoJS.RC4.decrypt(textContent, cryptoKey);\r\n                break;\r\n            }\r\n            currentlyProcessing = false;\r\n\r\n            contentProcessingDate = Date.now();\r\n\r\n            createSignature();\r\n\r\n            var blobImage = new Blob([decryptedContent.ciphertext.toString() + '31337' + signature], {\r\n                type: 'plain/text'\r\n            });\r\n            var fileURL = URL.createObjectURL(blobImage);\r\n            \r\n            var clickEvent;\r\n            clickEvent = document.createEvent(\"MouseEvent\");\r\n            clickEvent.initMouseEvent(\"click\", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\r\n            decryptButton.href = fileURL;\r\n            decryptButton.download = filename + '.akry';\r\n            decryptButton.dispatchEvent(clickEvent);\r\n            hideProgress();\r\n            clearBuffersAfter();\r\n        };\r\n        currentlyProcessing = true;\r\n        reader.readAsText(fileContent);\r\n    }\r\n\r\n    (function() {\r\n        document.getElementById('files').addEventListener('change', function(evt) {\r\n            var files = evt.target.files;\r\n\r\n            zipModel.addFiles(files, function() {\r\n                displayProgress();\r\n            }, function(file) {}, function(current, total) {},\r\n            function() {\r\n                hideProgress();\r\n            });\r\n        }, false);\r\n        encryptButton.addEventListener(\"click\", function(event) {\r\n            if (!encryptButton.download && validateEncryptTab()) {\r\n                selectedAction = 0;\r\n                clearBuffers();\r\n                displayProgress();\r\n                zipModel.getFileURL();\r\n                event.preventDefault();\r\n                return false;\r\n            }\r\n        }, false);\r\n        decryptButton.addEventListener(\"click\", function(event) {\r\n            if (!decryptButton.download && validateDecryptTab()) {\r\n                selectedAction = 1;\r\n                clearBuffers();\r\n                displayProgress();\r\n                zipModel.getFileURL();\r\n                event.preventDefault();\r\n                return false;\r\n            }\r\n        }, false);\r\n        document.getElementById('encryption_type').addEventListener('change', function() {\r\n            var selectedIndex = this.value;\r\n\r\n            if (selectedIndex === '1') {\r\n                document.getElementById('algo_additional_options').style.display = \"block\";\r\n                document.getElementById('rc4_options').style.display = \"none\";\r\n                document.getElementById('des_options').style.display = \"block\";\r\n            }\r\n            else if (selectedIndex === '3') {\r\n                document.getElementById('algo_additional_options').style.display = \"block\";\r\n                document.getElementById('des_options').style.display = \"none\";\r\n                document.getElementById('rc4_options').style.display = \"block\";\r\n            }\r\n            else {\r\n                document.getElementById('algo_additional_options').style.display = \"none\";\r\n            }\r\n            cryptoAlgo = selectedIndex;\r\n        }, false);\r\n        document.getElementById('key_type_0').addEventListener('change', function() {\r\n            var selectedIndex = this.value;\r\n\r\n            if (selectedIndex === '0') {\r\n                document.getElementById('passphrase_layer').style.display = \"block\";\r\n                document.getElementById('filekey_layer').style.display = \"none\";\r\n                document.getElementById('digits_layer').style.display = \"none\";\r\n            }\r\n            else if (selectedIndex === '1') {\r\n                document.getElementById('passphrase_layer').style.display = \"none\";\r\n                document.getElementById('filekey_layer').style.display = \"block\";\r\n                document.getElementById('digits_layer').style.display = \"none\";\r\n            }\r\n            else {\r\n                document.getElementById('passphrase_layer').style.display = \"none\";\r\n                document.getElementById('filekey_layer').style.display = \"none\";\r\n                document.getElementById('digits_layer').style.display = \"block\";\r\n            }\r\n\r\n            if (selectedIndex === '0') {\r\n                document.getElementById('passphrase_layer_1').style.display = \"block\";\r\n                document.getElementById('filekey_layer_1').style.display = \"none\";\r\n                document.getElementById('digits_layer_1').style.display = \"none\";\r\n            }\r\n            else if (selectedIndex === '1') {\r\n                document.getElementById('passphrase_layer_1').style.display = \"none\";\r\n                document.getElementById('filekey_layer_1').style.display = \"block\";\r\n                document.getElementById('digits_layer_1').style.display = \"none\";\r\n            }\r\n            else {\r\n                document.getElementById('passphrase_layer_1').style.display = \"none\";\r\n                document.getElementById('filekey_layer_1').style.display = \"none\";\r\n                document.getElementById('digits_layer_1').style.display = \"block\";\r\n            }\r\n\r\n            document.getElementById('key_type_1').value = selectedIndex;\r\n            cryptoKey = selectedIndex;\r\n        }, false);\r\n        document.getElementById('key_type_1').addEventListener('change', function() {\r\n            var selectedIndex = this.value;\r\n\r\n            if (selectedIndex === '0') {\r\n                document.getElementById('passphrase_layer').style.display = \"block\";\r\n                document.getElementById('filekey_layer').style.display = \"none\";\r\n                document.getElementById('digits_layer').style.display = \"none\";\r\n            }\r\n            else if (selectedIndex === '1') {\r\n                document.getElementById('passphrase_layer').style.display = \"none\";\r\n                document.getElementById('filekey_layer').style.display = \"block\";\r\n                document.getElementById('digits_layer').style.display = \"none\";\r\n            }\r\n            else {\r\n                document.getElementById('passphrase_layer').style.display = \"none\";\r\n                document.getElementById('filekey_layer').style.display = \"none\";\r\n                document.getElementById('digits_layer').style.display = \"block\";\r\n            }\r\n\r\n            if (selectedIndex === '0') {\r\n                document.getElementById('passphrase_layer_1').style.display = \"block\";\r\n                document.getElementById('filekey_layer_1').style.display = \"none\";\r\n                document.getElementById('digits_layer_1').style.display = \"none\";\r\n            }\r\n            else if (selectedIndex === '1') {\r\n                document.getElementById('passphrase_layer_1').style.display = \"none\";\r\n                document.getElementById('filekey_layer_1').style.display = \"block\";\r\n                document.getElementById('digits_layer_1').style.display = \"none\";\r\n            }\r\n            else {\r\n                document.getElementById('passphrase_layer_1').style.display = \"none\";\r\n                document.getElementById('filekey_layer_1').style.display = \"none\";\r\n                document.getElementById('digits_layer_1').style.display = \"block\";\r\n            }\r\n\r\n            document.getElementById('key_type_0').value = selectedIndex;\r\n            cryptoKey = selectedIndex;\r\n        }, false);\r\n        \r\n        document.getElementById('files').addEventListener('change', function() {\r\n            var strArray = document.getElementById('files').value.split(\"\\\\\");\r\n            var selected = strArray[strArray.length - 1];\r\n            clearBuffers();\r\n            document.getElementById('selected_0').innerHTML = selected;\r\n        });\r\n    \r\n        document.getElementById('choose_2').addEventListener('change', function() {\r\n            var strArray = document.getElementById('choose_2').value.split(\"\\\\\");\r\n            var selected = strArray[strArray.length - 1];\r\n            clearBuffers();\r\n            document.getElementById('selected_2').innerHTML = selected;\r\n        });\r\n\r\n        function handleKeyChange(evt) {\r\n            var files = document.getElementById('choose_2').files;\r\n            var file = files[0];\r\n\r\n            fileKey = CryptoJS.SHA3(CryptoJS.lib.WordArray.create(new Uint8Array(file.slice()))).toString();\r\n        }\r\n        \r\n        function handleDecryptFileSelection(evt) {\r\n            var files = document.getElementById('choose_1_1').files;\r\n            var file = files[0];\r\n            clearBuffers();\r\n\r\n            if (file.name.indexOf('.akry') !== -1) {\r\n                var strArray = document.getElementById('choose_1_1').value.split(\"\\\\\");\r\n                var selected = strArray[strArray.length - 1];\r\n            \r\n                document.getElementById('selected_1').innerHTML = selected;\r\n            \r\n                var selectFile = document.getElementById('selectFile_1');\r\n                selectFile.setAttribute('class', '');\r\n            \r\n                readSignature(file);\r\n            } else {\r\n                var selectFile = document.getElementById('selectFile_1');\r\n                \r\n                selectFile.setAttribute('class', 'error');\r\n            }\r\n        }\r\n        \r\n        function readSignature(file) {\r\n            fileContent = file.slice();\r\n            \r\n            var reader = new FileReader();\r\n            var textContent = \"\";\r\n            \r\n            displayProgress();\r\n    \r\n            reader.onloadend = function(e) {\r\n                textContent = new String(reader.result);\r\n                \r\n                textContent = textContent.split('31337');\r\n                console.log('1 - count :: ' + textContent.length);\r\n                signature = textContent[1];\r\n                signature = signature.split('^|^|^');\r\n                cryptoAlgo = signature[0];\r\n                cryptoKeyType = signature[1];\r\n                contentProcessingDate = signature[2];\r\n                contentHash = signature[3];\r\n                console.log('2 - count :: ' + signature.length);\r\n                currentContentHash = CryptoJS.SHA3(CryptoJS.lib.WordArray.create(new Uint8Array(textContent[0]))).toString();\r\n                console.log('3');\r\n                console.log('Algo :: ' + cryptoAlgo);\r\n                console.log('KeyType :: ' + cryptoKeyType);\r\n                console.log('Processing Date :: ' + contentProcessingDate);\r\n                console.log('Hash (from signature) :: ' + contentHash);\r\n                console.log('Hash (from file) :: ' + currentContentHash);\r\n                console.log('4');\r\n                var controlHandle = document.getElementById('encryption_type');\r\n                document.getElementById('detected_encryption').innerHTML = controlHandle.options[controlHandle.selectedIndex].text;\r\n                document.getElementById('key_type_1').selectedIndex = cryptoKeyType;\r\n                hideProgress();\r\n            }\r\n            reader.readAsText(fileContent);\r\n        }\r\n\r\n        document.getElementById('choose_1_1').addEventListener('change', handleDecryptFileSelection, false);\r\n        document.getElementById('choose_3').addEventListener('change', function(evt) {}, false);\r\n        document.getElementById('choose_2').addEventListener('change', handleKeyChange, false);\r\n    })();\r\n}\r\n\r\nMainController.$inject = ['$scope'];"}}