diff --git a/dist/files_reader-1.1.1.tar.gz b/dist/files_reader-1.1.1.tar.gz new file mode 100644 index 0000000..58461f7 Binary files /dev/null and b/dist/files_reader-1.1.1.tar.gz differ diff --git a/files_reader/CHANGELOG.md b/files_reader/CHANGELOG.md index 3eaf28b..b018068 100644 --- a/files_reader/CHANGELOG.md +++ b/files_reader/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.1.1 - 2018-01-19 +### Added + - signed package for publication in Owncloud marketplace + +### Changed + - updated bitjs unrar.js and rarvm.js + ## 1.1.0 - 2018-01-18 ### Added - Reader now supports PDF diff --git a/files_reader/README.md b/files_reader/README.md index ca15d34..fb39ab5 100644 --- a/files_reader/README.md +++ b/files_reader/README.md @@ -109,6 +109,7 @@ The same Android device showing a zoomed-in part of a page|![The same Android de [Epub]: http://idpf.org/epub [CBR and CBZ]: https://wiki.mobileread.com/wiki/CBR_and_CBZ [balaclark]: https://github.com/balaclark/HTML5-Comic-Book-Reader + [PDF]: https://en.wikipedia.org/wiki/Portable_Document_Format [pdf.js]: https://github.com/mozilla/pdf.js [SS01]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-1.png "Reader showing day/nighyt mode" [SS02]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-3.png "Single page full screen on a small-screen device" diff --git a/files_reader/TODO b/files_reader/TODO index 362b435..32c2f5d 100644 --- a/files_reader/TODO +++ b/files_reader/TODO @@ -1,11 +1,7 @@ - bookmarks - annotations - settings - - rtl and ltr - - test canvas size restriction - - test internal links - - add IDs to highlights so they can be marked when hovered - or when related list item is hovered diff --git a/files_reader/appinfo/info.xml b/files_reader/appinfo/info.xml index 376cf16..736f66a 100644 --- a/files_reader/appinfo/info.xml +++ b/files_reader/appinfo/info.xml @@ -115,6 +115,7 @@ The same Android device showing a zoomed-in part of a page|![The same Android de [Epub]: http://idpf.org/epub [CBR and CBZ]: https://wiki.mobileread.com/wiki/CBR_and_CBZ [balaclark]: https://github.com/balaclark/HTML5-Comic-Book-Reader + [PDF]: https://en.wikipedia.org/wiki/Portable_Document_Format [pdf.js]: https://github.com/mozilla/pdf.js [SS01]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-1.png "Reader showing day/nighyt mode" [SS02]: https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-3.png "Single page full screen on a small-screen device" @@ -140,7 +141,7 @@ The same Android device showing a zoomed-in part of a page|![The same Android de [SS22]: https://github.com/Yetangitu/owncloud-apps/blob/master/screenshots/files_reader_PDF_006.png?raw=true "Reader showing PDF in spread mode, thumbnails in the sidebar" ]]> - 1.1.0 + 1.1.1 AGPL Frank de Lange @@ -150,6 +151,8 @@ The same Android device showing a zoomed-in part of a page|![The same Android de https://github.com/Yetangitu/owncloud-apps/files_reader https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-1.png https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader-3.png + https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader_PDF_005.png + https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/files_reader_PDF_006.png https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_17-22-00.jpg https://raw.githubusercontent.com/Yetangitu/owncloud-apps/master/screenshots/photo_2017-03-15_17-22-02.jpg files diff --git a/files_reader/appinfo/signature.json b/files_reader/appinfo/signature.json new file mode 100644 index 0000000..85ced50 --- /dev/null +++ b/files_reader/appinfo/signature.json @@ -0,0 +1,132 @@ +{ + "hashes": { + "CHANGELOG.md": "be42550cf1ba12cb2e4c284a12d787c1248006bb67bfd8310701970f31df4d78cc7f7b27fb1ff936c2bd34551a55f15a4c52821937f2f22e55ff9842c75e2347", + "README.md": "a64e6b4b4eacc77006c0b406308f56ead93c893bc5588f734cc5196aa4bd2c7e90e9861a022a3c6545c614b7fd915d527de11ca2d4c3ae2ff759d44f77c7eca3", + "TODO": "abec9035615be381c012c12229835c14f27a19ce92a82e6286f068376a6bbad0fa1dff4d091810fed694b51702359f147bf63c54ac755d0433df36fcaa415e3c", + "appinfo\/app.php": "c1289bdfe9cfd5c83a1f2768bf052cc36a222e99c96740f528b8a537c70a55c42751662f8fc1b027c610a59ad4f6aa21237dde827d1e41f4ba3538d857716c25", + "appinfo\/database.xml": "111a18a81749237ad4e23c94f0b0986e08964c8b1ae5495b0dfe082f4801dc8951eb7c862f96edc8493eba1c4808c2227cde1ab48572d806b026c37abab07a85", + "appinfo\/info.xml": "ca9058e0edcd8f907ca07e5cf3b2bd0fe621fbf3145e9ca57f49857bd802ae45ab64dacba0a1766f455e7d6d62c23f10e028133b142ce272e42a4708bf9c9599", + "appinfo\/routes.php": "57153da351163ca15b81e023a548257e7d31baeb32785fbf5132418b0393949d3590a8ee119b2f6ae8c0b65b05ac4b5ae97cd9e9b2889576efc2bfb890684c85", + "img\/app.svg": "e4232de28db93900ea90cc91e60e26daccd137b5ffed7243edf9bc45b51edba39e917ca2875fcfcbf0a3b741173e99b8c2eff7ad371c40d5617aec74b56e6a68", + "img\/book.png": "9804b463779b32d1b8d9ced85a11f7e3201d9aef9a48b55b1381ae6addf19a78f5a3990c7201ce5702e798fd6bfad36c7a8e11e699f851351adf9b5b85cb3e68", + "img\/loading.gif": "4ce13c9402690a9beee76c8f6aa21ab48211377ef679e1b5d0ceca26f231a7ceecb2f00c0ad4facafa922e292e4afbde64cd85360e3a06d45ee1a71ca0e1a4c8", + "js\/lib\/Blob.js": "b0c7760f8b8365d39baf3a6320c2259660cadc5a4a877f35ef212ccfaee645a48ac6b754536d716539841c62a96f2b5036fe1087a0cb3c4b4c6b6fa34d406021", + "js\/lib\/blob.js": "c04ed3426cd6688e970818a6494bcb9be02ac69f72ad0ca9121af8e20092b602d9595f8061fab5f69e538e4b0606ea6eb9a142cb40ce36adb34163c917004832", + "js\/lib\/typedarray.js": "e8fee5f0cbd4e5282083182ee7ec2cc6c6f86d6d1f0c259853612983b1ef5cd1187061546baadb1eb0f8629dbaaa3bb4520a4d161f5acf932503ce7e52a3a6c0", + "js\/lib\/typedarray.min.js": "c78aa9dc295212548ac927783c62f1a5a5ff56c05164999f09d0ac5ea6a98afbe71aaa4e45eca469e379d920cc73beccbdebdd25f9797335f5b361fc4d87d09c", + "js\/lib\/wgxpath.install.js": "afbb4af1de778f5d135ef4be4d4eea98d27a323a139463d06b3f0b2c4cea00730e45d8414a0e74eace952c634f87e383a925c132bae043216312f9425a1b246d", + "js\/plugin.js": "8816cfee3553eb86c83f6b183ec5e667136619cb83654fec0372ff6846099557b793a7fdbbef228d76433de3f5b06fd93479902ac3f57135b5b645bbc632b6d4", + "js\/ready.js": "a3fd42592fa94fa2d573b867238f5e35780681e218dc1aa23ce8a8afe66614ea0d8fa94abda4c7b7ab595727cd724c75d452a97bb0819b2d35fe2e145c985f00", + "lib\/Controller\/BookmarkController.php": "1e1d680f5bcbf5edc49df09a696d011920d8695e305bebcc1c87cc9283a73a5ec8770a264312b8ec80c72f45855ea0baeb2753a7d7df05befb0c29db50ed692a", + "lib\/Controller\/MetadataController.php": "23e23b95c8c15d0ba5be797b26babb315703430251967fb536e267f3cd64af7047d1953e3299940db8acfecc2a87f5339220d37c0241b254fbf524c938a55053", + "lib\/Controller\/PageController.php": "0b6520136983eee131d0369fd6958dd19bb7cb0486f5a8ca0147eacfda120cf339f4dd2c61f3ff74eb87795063325a465d1036c002fb5d307315066160ee10f5", + "lib\/Controller\/PreferenceController.php": "3f3ced2dc68698f25dc0f4732d1d4dfdf5064a75102a0774acb5e6823b15b54651eecc7157214adb8de1ab9b18bd961085a8eb79edc6304576ed5bb8fbc18e94", + "lib\/Db\/Bookmark.php": "0eeea4cba7b182896acb9b630f0c5f076ee808468bda6a1c75dc8d2b369ace2e7942602a4151a43b40351e6f12b18bb34484eac0ed3d7f0a9d85769588da7674", + "lib\/Db\/BookmarkMapper.php": "eed3576c947e0506c7769a73ab27b3651efa4596eab297dd26fe2caa32eb9c57d95bda3915f7105c60c560196d6e14cac3c764aefda2a35111172e04b604e367", + "lib\/Db\/Preference.php": "e4edb4df45318e434a3d575473e8de64425d212b1bafbfaf90344616a17e4a7be7a69f3657e1179c1cc2e28e20573698a7449d70fbfdfe7a4097298800415975", + "lib\/Db\/PreferenceMapper.php": "4697ffe43030475d9091c3ce56936a7435533186f1ced6bebe3f07bbb47e8a59fa00758f77d2d27b8c13ed766d647450d7709e7b174c4da6e7bb0115e5c44988", + "lib\/Db\/ReaderEntity.php": "cb76626c5c4f2d177756093ef7f836c5365724c4ff8906a57056bbc85563ddc91118faf5efa0cb295a9e533680d38bf51cdf78ec2dc25bd7a4f0737457e0cfdd", + "lib\/Db\/ReaderMapper.php": "c8d44cefe4c1b3de1e55e71367c7d7e07630adbfd29027d29e06a4f04559c7ea869ccc28c862af439dd35042f8bbf7019cb5cab9bbd47c616ea99e28d222326d", + "lib\/Hooks.php": "a6e3c2a8b662d947954ea3326b3496a7f4e68af7eb4a8a25f28b6064d8c4fe2fb9a572e6ab2f0e39cc7c1e271c4a2f9ca50bdf2f6382bcec6a3b6a81e21647ac", + "lib\/Service\/BookmarkService.php": "7df012686e8d1e9a4668738d82edc51ca0da8e584767737091053bb48bcb896f11b03262f5e20dcd030a65af9c524d24003b3405679fbc23f60d0bb5d84eba15", + "lib\/Service\/MetadataService.php": "7bc4ab9cdd16ced31f46ba137fa1efb4d6ef4784f947886e8affe667bf7b51c532bdc079e9033e774db4ea30a8da1000df958fc6e15e518bd920995dccc729cf", + "lib\/Service\/PreferenceService.php": "2b52a28a074eba355154cbdad80358aaac394635ca91698ec3d7876eee0dc7e154064d8fbbe5465e7bbc783e618fbbf9ea1f07acd3cc4ce5b84116f7d8aed81c", + "lib\/Service\/Service.php": "cdf97b612fde0bec7846c0005280f1492d63e705b753c4aeb1df2c2ad2612a122d49eb15b6e7dfbe7fd7320762171a6ac6324181511dc28ec0e1e27092872eae", + "lib\/Utility\/Time.php": "58f760099eaf647718b491a7c21012398906bbe3ac7363aeceffff1a98d952f9a76697ddff2c00abe25e6c8db1cdf4d5994c1ab7d9474a05afb76b444ab9fed6", + "templates\/cbreader.php": "fcc9db0e1c195a1718d47fac3a1134211ec9049d6a91df49132c6cd87660a85d931fd3c4105d2da48129e60f08aaeab679f6672fb74fc9a464fc892aa1fc4cbf", + "templates\/epubreader.php": "2cf4fc9e81ff7627b3a920b4616284bd546a72c2441a9dfe2be974d21a686fab45dbda7535a0c58a67ea7af3defdfc319553e483497360ff29a7985788ba1e4e", + "templates\/pdfreader.php": "c53cfcc0edb8b269dbf8d2cf5d9291ac5fa00cbed52a3ce5413464ba8d72bd43c75b0753cd03cb8c4f685fe72399aa0f4146b43256895ccfc4731a38d7b34d1e", + "vendor\/bartaz\/jquery.highlight.js": "2071d929cf62d8ef6cb85df2bef1d556d21c06fd23233e4938e8ba43df794ebb167b7ef75a50c10f01c9c59af76ae4278f5d254d1b0dcfca1a7201c35cfe2e33", + "vendor\/bgrins\/spectrum.css": "0d51df46221e84245609bf96f64fcf3aafdb9d2588a14e94382e78e605763bca1fd652adbfdacfce2324ea2d264baa3f1922a628e8c6ff55d4cc221ddbe05c15", + "vendor\/bgrins\/spectrum.js": "a7e0d8302e03348effecea4cad9cb59ed861d5268552d4829af68b4d77f2022ddb46817b5a419e57f17c19e8eae48d43ae6ba858258c71f9bd658930b4484b21", + "vendor\/bitjs\/archive\/archive.js": "e1d47d6129c54faea42c572e37502bd44f4af70710e9897c0dd6f1e064edcaac9e6bb77d9eb6b93e659769d87c52381875ee4e00b9f1e4e66c8ddd976951a1d6", + "vendor\/bitjs\/archive\/rarvm.js": "7257ecafd56b2cae8e2ed4abdad429ad133c3ddd9271505750248a9008915a619d996c583e832b722c5757f6f3ca8b8dd20043af076a9ddc93e043917d685f69", + "vendor\/bitjs\/archive\/unrar.js": "be2368d114be905df3f32be2928fc7204446d0ffd60bd68d50624e79cfd58f6684279f6b3f1a7d43413f1ae25f9bd0b88c398a9229e31a1c80ee58d54f1a5775", + "vendor\/bitjs\/archive\/untar.js": "c76b6d7bf6e9ebb0c0837a083adb059c88f4054521e6d0e00e6e6b83119f194127b76473e7f61c507ad7c0802cf94089f07971c0ad61450ae2b5f1745758a691", + "vendor\/bitjs\/archive\/unzip.js": "6e96afc92d455895f4172a932cec5829e67b9366d01cb57992a844ed494c98b550b4ca61b2ffaca0b7b9094cf2da9ba6054e939b55732e040be87685e7760cdd", + "vendor\/bitjs\/io\/bitstream.js": "526d7463d45bbe9d05461becfbbd6d8d397b46262400196714fe7a93110b36766ad224ee55de8a8c1952e337336ba735a36530877c06de85aa3e691a3370ff67", + "vendor\/bitjs\/io\/bytebuffer.js": "1415e0730090cbf4472cb9933eabf15bdd4788029a18315b9f4f04b0cbcc59623b109f0d8561700c8341735e5a102c915a27b2fdf961aea8ca5958dd4ac2b0c6", + "vendor\/bitjs\/io\/bytestream.js": "7f2114a7baae81bba59ac90982a54e715aab736624f313148449b8f0aa3cafce1a83d154f395327a0fbbc74b756f820068c08fcb782789195477d87664678e97", + "vendor\/cbrjs\/cbr.js": "170fa1f23c9bf4fda864f70e90b7c54ff093672901ef8fc0f26b126fd955ddddb172f25dfdac4129e7fbd9f05489143c0fe9f418474546668b8c41d38e2df7d9", + "vendor\/cbrjs\/css\/cbr.css": "4fc0b73984b16568b8207b8c5fe35a15f5eae7d7fe336034870f4fa384be5f0489c02ee639857d18452fdc4a14ce2a8f6151fd2ebda9bd97e5152afc0bc81587", + "vendor\/cbrjs\/css\/idevice.css": "475870d07554bf15bfae371f7c91e5ac555aaba20eb29079471e4856f1f43d0d2dffde756420bde094e3fdda43b6f12379bf694b64ea1cb862bcff4042a94af6", + "vendor\/cbrjs\/img\/loading.gif": "83773895f43e75bd31209664494da8c89f1d3869cba24930d71a3e7090b4b38dcc0a31c9e1b764d763f586534c64996e72eda2fe035a7b485a28c33b206c96f1", + "vendor\/epubjs\/css\/annotations.css": "9600da17ca67c7372bae1bd951cc933de1d8ccf8c4c43f2a7b6bea71117141dc355935f693f8e3be9d3f87c027b3221d54085c6125a24d0edc65ffe985855780", + "vendor\/epubjs\/css\/font\/fontello.eot": "06dd0ad0f1367f0811db348865be15f6dc153cd1bed819bf0abcd1ba1d19f9910047bee178f12c7d2334620734f6a1f9e8001eb28bb53959f536a765729901a3", + "vendor\/epubjs\/css\/font\/fontello.svg": "183e8846244045b8891458572bf3b8a51b6a019aa6a374ca30481fc403df7d0225aaf648e8dc7ecfdb0c7abfe3d5d8a5d5d91d5dcd7d8b456e776d38c05e652e", + "vendor\/epubjs\/css\/font\/fontello.ttf": "122beb1963a58e2a6d30945f37e5c7e7f12d382965d4352f94230adef47a446393d5b10148d445f42c201a72901f955806dafc0b4e3a569cbcf9504008118a8e", + "vendor\/epubjs\/css\/font\/fontello.woff": "45723570e0dd5b60bf2b9508f46e28b015a2b7f27bce3528410affa77a6704817e4f4885fdce968987b5bf27092237903d8da2ae20c2d6bb13482e210dd64a72", + "vendor\/epubjs\/css\/idevice.css": "57f16116dac978222fc6ecc989b1bd97e5b21b783824d8b5108761a8e2ed3e7cd31fdb587f947bb86037af0a7b258b74458eae04f13508cf61b59bddc40e4c83", + "vendor\/epubjs\/css\/main.css": "5b646c47a8729740334e8212810d6a7329550164e8b26d55b654f7ec136d2bc98bac7aee3fa83de0cc81bbd0a1060a3e4032c216b6d50fd4cdc19610ec3bd310", + "vendor\/epubjs\/css\/normalize.css": "2640cf3ac3153b95939d2c6d1b6903d24a906d7737d48f79cda4e0e6bb41098c18b0d345deb1ce41d5d27f734d92b558c8f857e9909eec23bf8147abbd4a0fd7", + "vendor\/epubjs\/css\/popup.css": "d44a1a4647f2216ca0698300d9e462b6e5a57b19a68c93642a46bdc7681caad89888c1adbbf4e5322a6789d81dc00ab102001fcd761187f87ff330d5fde428fa", + "vendor\/epubjs\/css\/sidebar.css": "1d7835670fdee603aba9af5c715be34c327ccf963f6c8de4b9c6892c876301dc643d1d2203e1f5f263e83978cf5702e80bbb945cee138951db22e53457355781", + "vendor\/epubjs\/epub.main.css": "8f11961b3353679ea1ffe3ce2744421ed005c4d50b160e3378163f2cbea739fa5ab4eb5f8b727f5aebfdd0cdd996bf6a9de9fc762aa36327d47e92bf1a1ce8c6", + "vendor\/epubjs\/epub.min.js": "fe300613fe1f868c5c5c79e4f35b40c1155113ff540d8d68a1b04b642354a691eea6a9e2826fb9636e34505939fc69a60dba985674fd75b6b2a66b634f80651e", + "vendor\/epubjs\/epub.min.map": "8876e8186958c5425d0aa61f3b421119b52df007d4e1c460213d14e5f10c9950e11fff0579800e02ee8b44ce7bc71fbe72e45c1f216bff4b228a149d5283ad73", + "vendor\/epubjs\/hooks.min.js": "85852cb5097c502e4f681f8e0e0d9e77ef085ce607379541475c8a11d22d9e6593095a104c29a94565e41dbce853a9388c3a65454832bd768d1187dc6756fe85", + "vendor\/epubjs\/hooks.min.map": "2cc2bdd48db5909337225209b489345e7c545594ac1037c09981dcfd3215dc2c87c91084442c83f2b1daf881e5013c41d861c38bc18199771072dc853be3313c", + "vendor\/epubjs\/hooks\/default\/smartimages.js": "d3fbe0efe4cc9b6c8efc23a9d2ac729d92a1ef5fdba12be988be5979381c2d8de7385e1ddf5575fe1ed9863f15be82489a36436dd68ee70c2eace92d22ff8fe5", + "vendor\/epubjs\/hooks\/extensions\/highlight.js": "2acf2004de04837dd2bf678af8d6c960023c0228cae734d90df98996a7d02be788db20e9ad7c1fd757aa09366e6ee491e2eaafb9917cd4a95a129d583521516b", + "vendor\/epubjs\/libs\/jquery.min.js": "0d40bccaa59fedecf7243d63b33c42592541d0330fefc78ec81a4c6b9689922d5b211011ca4be23ae22621cce4c658f52a1552c92d7ac3615241eb640f8514db", + "vendor\/epubjs\/libs\/screenfull.min.js": "a09c4e0b145c226881398ec523cbd560ebbfdfeada44d41e2c1df27d0ac9de9839875cbbdcabd61febab37145e58e76fdd49f98062f05c48416244326ca7a117", + "vendor\/epubjs\/libs\/zip.min.js": "6ff9a48ad45127627e59e63a11d533663c608c73147d3a372774132cfc7f3b743268d3fb65cf177cbd56cd7fd105e9dfd948c463d1407fb4b0623df1d3397474", + "vendor\/epubjs\/reader.min.js": "0b6a37155d319141ddf06245bf1166640bad54d51f62abadbbb2a2ef03abfb1b2055810e29629060193ca5a80ef23c593cbc661d1806529c9debfe22cd505a12", + "vendor\/epubjs\/reader.min.map": "0374d1db0db30c48a25f4f40c206aeeaf5e323b528a1794cace3aa6de85499ba58577b8d85d1c2004f554154ffe2f1abd4adf42c7b28c6c0f64cc3eceb07a06c", + "vendor\/icomoon\/fonts\/icomoon.eot": "1296c03ecf92f70094c6e0cd4568e71604c956aa3f748fc45fd08b509e2b3680e9c83356116cea2f7ae2d60252eee106dff80d1a07550befa61b87f3ca6e2b71", + "vendor\/icomoon\/fonts\/icomoon.svg": "2cea5dc6e31ce32598f7543274443689a6940ae2d6ecd2fd7dbf25d3d967a804725afddc5446540a98ae11d92df85e4e8703aa4116d6d9c71b8bef4dd387207b", + "vendor\/icomoon\/fonts\/icomoon.ttf": "3355c12d54207f9a4e5f23728c43383d1191481a77cf102383bd5e036b59ca029a7265c36ae96ca6d1991df8446bc6891f01d81675473628e5bc26dc2e177d6d", + "vendor\/icomoon\/fonts\/icomoon.woff": "44a9098f464bf9e80000b2cf89096f2b07ee046127ce5c11005a31ebbfafd7475e56de7eebe96ad9cee7cba4da96df0a7fa6c816b17310bbde38f07fd40034d6", + "vendor\/icomoon\/style.css": "e949b8af266b96651ff40bed393a8f61f4d037b56ab9751a40845dc05f59103d58cffbe444038e8dcdf726e7da007e55c28b196fcab36148388e756174b71bad", + "vendor\/jquery\/put-delete.js": "2447c4937da33d0d8d567405db3e3bb43faca00576622edb65ddb592c4545a4bbc3259ea2e0f5f71ff425db4a33e0359250ee13718a6e80f3da97bdae7960afb", + "vendor\/pdfjs\/controllers\/.bookmarks_controller.js.swp": "e78a4b3db303865181e839f0999b1df715d786ba4f9678599e6c37c4754ae1dae22433f1fb1a8bad3e9f618fe0351249a9509d197e8413aa4695b24a342dd11e", + "vendor\/pdfjs\/controllers\/.progress_controller.js.swp": "68ef1ef094fc94d91d027a9fb86d1424141b576e11b26309b4dabf466a5a1dc3206e8551b29d7cd96dc2d01e2f90266d44c121c8762352a41a22fb2cb3484d0f", + "vendor\/pdfjs\/controllers\/annotationlayer_controller.js": "8cecf74b113e7738e1168000bc27dc30ad707b7768bb668b4dd3a0ff754e823681472894ba79a6438135e2ff49e31aca35e86a848065023313622df6ac7f1fbb", + "vendor\/pdfjs\/controllers\/bookmarks_controller.js": "032e088c4f11cf053053845f6ed6fc72fc20a851d0aa52e202e64635b257c59f7e5225a523178779ad03c7ba04cfdf0a201e23b2a577f1c0cfae8b97d2695256", + "vendor\/pdfjs\/controllers\/controls_controller.js": "d71fc989eb49ba6ebe6a61c562c42845d3a2d325770e09d66be4353945871fbbe9163df7dd3e47c713657c79918cb51518fc8131d4eae2a99b2d4ada24be7fb5", + "vendor\/pdfjs\/controllers\/meta_controller.js": "fdf4620f401e0ad27da9e3d91aa18e91d7666623cbe598bc1c92127e2fff0c25f9c089767e0ad5ca1ece5a621b8916a61a60b10e0a2bef76a4bf013343bc0dc6", + "vendor\/pdfjs\/controllers\/notes_controller.js": "19ddefe3dda1774931209bd2ff7080912fee9015eaaa25cc786a9c02de85692a4190fc68a2840c3da836d31ff20e377e4dbbd0a699f73cd366aaae1973294985", + "vendor\/pdfjs\/controllers\/outline_controller.js": "c69fe71b155920cbf4825834cc7c7f6c91fbcbcabae4c892cf0b2d4a636db8faf9c25e54d58029544a12bfb631d1f4c74d9d7e1ed35cf10cd862a495efc1d891", + "vendor\/pdfjs\/controllers\/progress_controller.js": "9894b73c39a3b500fc057472a7ec01e876bdd6e6d8d87dce12a46698a9847aaad576294e05fb9a33d649659a00549b67921d66c04216101c61d1c75db0f8e828", + "vendor\/pdfjs\/controllers\/reader_controller.js": "2e95d778a13b3dc950762d57bc5cb0c503f1c4971ce0c332678b8283527f3fb075be099e0e7bd5471e52a3b868fd7d74af8b5c3160e9a2283f48b5d19fa64fda", + "vendor\/pdfjs\/controllers\/search_controller.js": "d44a327561e9fb67e535be4fcc307d309f4aea0ee16be23057ed0f41692de01a1cf69d3f7bc2b30b26a7bdf776df5d56ff9ee26cce94f37b5cd27d4e14d5a93d", + "vendor\/pdfjs\/controllers\/settings_controller.js": "e3cb86fe990bb69f4c1f553ccb30b619afb34123b3062882e66a0b9aafce15e88cc803d3a15852e2e2fa7ba6f0f4ab866044d09834f5e4365e71443a23c6dbc0", + "vendor\/pdfjs\/controllers\/sidebar_controller.js": "3071f59c01d6088c21f92ef36f7c6b15024ba3dea7bc005dc1921b14c9c1c6320f7eecd158e974f9b8592dacc488ef79fc38d4925978557b09fc12815a5b86b0", + "vendor\/pdfjs\/controllers\/styles_controller.js": "3a8817046dfae4dd166ffb337a6f06ab6ee9df2e60b45091f6b15176df03479a66379739ebabf5e61e2a0e7ac1dce4e107324e15216adef0e33329bf3747f241", + "vendor\/pdfjs\/controllers\/textlayer_controller.js": "ca23b356a61328cc1400fdad6b8fd52c04347187c385737f650680b326326d60816d921dd191a04e09abdf00669bd6ac2ca2140ab803986079c4e8d74df51c0f", + "vendor\/pdfjs\/controllers\/textlayer_controller.js.simple": "05f346ebf5ba57f8de6f47a5e13da6defdd0774b4e546101f4b5be1ee7b2e7848bd5b8d6c08e4ed1c7e5d3f4dfa36ec4682b7e9062adfba3ca4cfe9ded51643c", + "vendor\/pdfjs\/controllers\/toc_controller.js": "5fa9d62693e9f285450571c248084f236ed9bb75f5ed972864e35448c9bd1fcc51956e76be62349630365d915064c8de95f55e30ac6866114285f8b3313113e4", + "vendor\/pdfjs\/css\/annotation_layer_builder.css": "b01d778e71769bfbd9f494e3e992f9b4d1762851e10b0977b5f50285dfda011ac27ace43b10c32431997432859f8458dc04aeda1cb08429fd16141157681708c", + "vendor\/pdfjs\/css\/annotations.css": "9600da17ca67c7372bae1bd951cc933de1d8ccf8c4c43f2a7b6bea71117141dc355935f693f8e3be9d3f87c027b3221d54085c6125a24d0edc65ffe985855780", + "vendor\/pdfjs\/css\/idevice.css": "57f16116dac978222fc6ecc989b1bd97e5b21b783824d8b5108761a8e2ed3e7cd31fdb587f947bb86037af0a7b258b74458eae04f13508cf61b59bddc40e4c83", + "vendor\/pdfjs\/css\/images\/annotation-check.svg": "7442036525e2d5c0ca86c3e6e343bf79f39c9d39ea4815bcbea3056f157465821fa19ef559c7079ea60c7cf99ab4a01ad47af7f46e02f8ff2822893b947b14a9", + "vendor\/pdfjs\/css\/images\/annotation-comment.svg": "3b0e0c6fa42084f28edabbaabca1052afd76c3c41576f23ebee598960da96556ab088e8730206d816c6d1434bcb03b0ba36d50abce074dad00cbce99fdff841e", + "vendor\/pdfjs\/css\/images\/annotation-help.svg": "735e99c561fe8a509bb5375f77cff79c601f9fe82c3af9254a657bc2b6274a77ccde0014855ba1e925ea2beb207e0b0c6b138f3f78f41a7e9df71f5e58f2c8c4", + "vendor\/pdfjs\/css\/images\/annotation-insert.svg": "f8caef572ed87fb5dd3c421665cdd1f5e4f414a65148d3d9990bbec21d9adad86810c58610c800b7649f719d88a53fc924f0dda88b1cb7883e74b709774061c6", + "vendor\/pdfjs\/css\/images\/annotation-key.svg": "e9e8b365bd41ae612560f438c6aeb0d1aa2e55f223812b26bf6cabf44b39bf2e1a42b41980fe60187199cea0f2adf1f31c7a0860be10edbc595832542bb1d7e5", + "vendor\/pdfjs\/css\/images\/annotation-newparagraph.svg": "ae5816a3ba95cbff2bdf876f4f2f4a0bd7e347bdbaacc09a2e65d46d0edc256c7f0b896536ee5470a2d17cd903d3bae52bd506c12d77504ac0aefb25265eebb9", + "vendor\/pdfjs\/css\/images\/annotation-noicon.svg": "b74f7a79dc719acab1f351ac70f00455654dda140d2bc24eac6d48c804bf24ef5938c7d85073004e20b0b3c52f1c38f598f811e068e5b9092e11085d468af0ed", + "vendor\/pdfjs\/css\/images\/annotation-note.svg": "566be95c1dda2d5a52ffe0a6899f5058c547f91fcdc60dbe26a79b39fe427a79802d6d52eacb711acfee368318f7b0d54dc9067d88962306d4b0d4ed65d651e4", + "vendor\/pdfjs\/css\/images\/annotation-paragraph.svg": "f016ff103e8de8e6cf19aee5e7b627ccce075844e41395cfa20342a0b42a13dce82106e4b06bbb1d7e7c135b0dfb8fba0ab3b0703f40afb9625048076ea3558e", + "vendor\/pdfjs\/css\/main.css": "4ddc495360dde690d76b9efbd0c7fbe1bf1d1be84057cb607333d6dcd89eedfaa7de73413b13b670f5d310d80069b6886bfb0b216eaee1149b1fe3d16cd7d13a", + "vendor\/pdfjs\/css\/normalize.css": "2640cf3ac3153b95939d2c6d1b6903d24a906d7737d48f79cda4e0e6bb41098c18b0d345deb1ce41d5d27f734d92b558c8f857e9909eec23bf8147abbd4a0fd7", + "vendor\/pdfjs\/css\/popup.css": "d44a1a4647f2216ca0698300d9e462b6e5a57b19a68c93642a46bdc7681caad89888c1adbbf4e5322a6789d81dc00ab102001fcd761187f87ff330d5fde428fa", + "vendor\/pdfjs\/css\/sidebar.css": "aa4aa85bcc4e4ec3c40fccf59c671802ce1fa3eb49bb0c048d9a20361d56f0d0b24602ce17fb6cce4433b982147a565ef7b2922a7a88e8edbc636a47ed8d492f", + "vendor\/pdfjs\/css\/text_layer_builder.css": "1a723bcffea2832acc35cda3e90b0f7b241da62e2904309cdb61ec4fef9203ca198ad187abe24c007dca4a932a052f9f7f4e718fd86d915f1bb58f6c50227dc1", + "vendor\/pdfjs\/lib\/pdf.js": "2d7241061e30e69963a78c64345ecbb889b831ec72cdccdb07d0e684c9cf907bcf45e3781b91e51c1ca4258e796eed0a69d83e8945ccd98ace75cd57ca57d5a0", + "vendor\/pdfjs\/lib\/pdf.worker.js": "03cd966b7b23dabebbc1652e19f2511c41237d8cafcc8fef655b6424c1b5884e48fa3ea052d1ebafe3c6be096c0c6aec1c9cbad45115912a4a75eb886c591534", + "vendor\/pdfjs\/lib\/text_layer_builder.js": "f56f1d3b1a61a2b5ba4945a60057604d95a3595f2dec4e5c99b79db10f3b00a0e6be30169383fccda3a64aadda3f607f650ac261c47bbea7f0f6a3196b645f28", + "vendor\/pdfjs\/pdf.reader.js": "5d68a51aac6a3750a9264cfd97517eab9772dfd93c7e372f309095559410536176d583357c6342cb8933bb86d8f2ed9c41ff2824c575ef471da6de03a49e4631", + "vendor\/pdfjs\/services\/eventbus_service.js": "851b741ec0eb06a7298664d626e648613f86d3958f4c7045cadaafb5c146088952ce584d5a4079ea51b54f07fc0cb2e9a9ddfefe52a70b2162c083b10b6293bc", + "vendor\/pdfjs\/services\/link_service.js": "b227d4163e2fcb3db4ed0ee2dd9f0af59dd263bc05153139d9588dd536071ca6d6430be214795f440061bcce6c6685986b5b002e4c9af7d0e2268ed83fe43424", + "vendor\/pdfjs\/services\/simple_link_service.js": "ffaa00f383100c5c689da1f8bfbe3baa06fc42147acfa781356eb67958cc6fbf2c34d8f448afa7f5bb14a5132c43fb78b3ad6a469f2af32ac0e29c93aa7f7ac3", + "vendor\/pixastic\/pixastic.effects.js": "85bd5facd47936aa75e5e18bcbec62641448c909a97a3714d3741e1880cfaca31fa60d85940ae6f27257d895bc278e00c87867cb742fa0c6eeb85bdd5ce9b36d", + "vendor\/pixastic\/pixastic.js": "f090060b5977941be122cf285b279e9d28fb54f1cfe9f373c0866157aa7e124296745638d3ac92356b727f719220da95f968d830eed688908498c6d8c892c226", + "vendor\/pixastic\/pixastic.worker.control.js": "c913b34aaea57f6ef76075ab6c0e169431947611789766cda6914ade93e98c877ac75cf092f2db1ca0876a6b8cc28d2fd13d22398d08101b787548ce4d2603c1", + "vendor\/pixastic\/pixastic.worker.js": "f59136a3bdbbf33fa3f81ba0cefd33b81269bbc230e7900232c725139674e53dc070f8445081b32350bcaba70ab713d6426902d66986554709c1a48952396283", + "vendor\/pixastic\/pixastic_combined.js": "a69bff7c76e6cdce7de3184184114e10f2ddcb369a2de03b1986c9a74d71f67f038d452d60df4a638e12420314bdc5c052a791a98d22ae5347a5f43bffd8b2f2", + "vendor\/sindresorhus\/screenfull.js": "29d23b28b76827f037265ce60ef5cf76c0d560c7aece03593021feae9f6220c3170abf5a8b5f380885fe15e9204425fb5446fef61c3b0ca83d6f332eb1bd1571" + }, + "signature": "rQs5h9jU3MIQUuEl0yTgVtZu5XbF9bGlwKQkBGS8dquMOZIS8fAR7aTLt+IDcG6q+SLw5BoDhw+g19pKSa30W8ZiQWLunvnqCQuRWPCcqxE1IKeaZ4zxCsm7xZpdd3DpgQQ0Bi0uLr+4mgw9kwNF23EsUViYX+8qfGA6wQNsLt35ZF44JAJ8K8cKYzZezDHNdrM5598BBJ+VGVxJwGU5RylTAC5wjcTRojkGK73zNDBX99+4cbIFITWhLe911Al5fGdbOCJJVGxbtLoSa5mxOKb24OZjZys3kD2PzNeVmXPnhNRITDa9b0xPfQ00BDYPQEYGbK6riW7gW6Pm8tE6Ab+syUUH\/HCjafPeX9lYUhINLH30QY3wMzaJcWhfN+rXpom8BzUFQ3KvQCxyeena2MUZz1RmhrsMfd3kbzvT1nyxdw2LIqfurMRQ\/aRRnSygnnWveGsogOHmNp4O\/7RgEpfViAB4RIRp+xtwb0CQCQIgOY5U81qhwrTysGlSzrWQdo3iwYgY3IckR0vJ02gB5JRS1EjRMC1COYjuFeGnWOzkTKL+um\/LQvvO04gC5su5uVSr+P1+J\/V2VFIfE2WgeesPVlEk0Dmcgj2TAxPOKB6YVCYOoa3KD4JtajS30oHu6lrF6\/ijlDzgclKShT42PrxqOQC1mfvhkNBZnRV7KFs=", + "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIE+TCCAuECAhBPMA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNVBAYTAlVTMQ8wDQYD\r\nVQQIDAZCb3N0b24xFjAUBgNVBAoMDW93bkNsb3VkIEluYy4xNTAzBgNVBAMMLG93\r\nbkNsb3VkIENvZGUgU2lnbmluZyBJbnRlcm1lZGlhdGUgQXV0aG9yaXR5MB4XDTE4\r\nMDExODIxMzMyNFoXDTI4MDExNjIxMzMyNFowFzEVMBMGA1UEAwwMZmlsZXNfcmVh\r\nZGVyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2Dro3KQnJEnKeJVG\r\nnhKvrQSzLNyphcF5UNj4j3Km6wLcb86RkWtq6uX5eR6g0HI9NFZF3qxBLUGN8bpM\r\ngGyalTLwj5IsDYO\/naSZe\/wXNCBl82vZq+jjnDCYll7r2yNjTFVzRtH+o9AIQlmM\r\npt8+PCcw8n8QqlXUIq9A3kb8wggczEZnw6bCudDLQWXHYKD5\/tn7n06h9fA4VxfB\r\nQMyuv8hIjKEQqun3Qqvi3DfaR52sbeDvv9bGACxWqjiE3P6sZvL7MlDqJ5KeqWoM\r\n4qPGkgDusTtXuO7h3ro2H4NMydWXcrbUAPTXcAPo2jzTfhV8m9xQDc+45VlONjIp\r\nTFwV1oF53hnu81TlNniz1RTbDYMkExvPYtobNjNIR+VsOQs8Gq9iEDEIxyqCm2it\r\ncuMjeFhYr1rjyeS21i6cNtD\/kMxSFwKnluQPrb49pK6g2Nq5Go1iP8WgT12hAQhr\r\ni7wwH32bLe11xnD53ko6pAzhqmciaSHLxkZCm+eyTNwJzQa0uQ+gAD8gJ7bVQUxg\r\nPSjm1amfhMAzsHIraMFqzlz7IWjWA7vJGkR9DcweYBXsyt6ZloLekPsNxEKnuh3F\r\ngjBHEoy7iPLmDxGvTfPW76r6vBwBF9JgIrhJzRMtTHTsYX9olblQr957SLyiZaqJ\r\n\/kKCQZ3cKPhWBh1KydMjPlXbGFUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAcYdp\r\ntoKFBZV7rswQ9yL6Y8F\/\/VUM1J1jincG3soCz5\/n5rL0TDekS0FI8eNWX0tay0ne\r\n3\/FZ93\/fb+gkQf7KutU\/9EWZwnc90XNq+Q3\/3DWz+nIm3EFttz6GioVYz7XEAx3A\r\nSMWeWY05ei9V7SVSnqglhouhLENrKKI8ilzGI\/pEtCs3RUv3xi7GPBdCDnvqqeXy\r\nRHrP7ZFe3v1go84v1MwQOt4\/OtaYk\/4HU51oxzUI8yDMNtLNmZm7gqLbT9bRsWCz\r\n5gqFa15K4X7sVL\/ECI72zEDZsF0RtmTCp9fJLoYXIPPQ1CACi0K0hB\/ssE6BC9Zl\r\naUXcbZ2BLwvQiZmEUhyyr0WYK4D\/dE4LbYqYpDDGRhXpf4cRhQahsYL8aMzZtZfl\r\nNDE4PN\/4sV6id6MnwrtDmsW3frMlkhzrsm8ftzwkbIyJD1Io5OAOJn6oxN2sjlWD\r\ngof0tuweAlTGuAI7\/CUA2yMZb45MFkLWDExzZsiVy9UtU641cDzOxAbg7UIeTBRZ\r\nYUdl5ci1f8299Yridc4n70yQg2GHwa8YJ6p42f93sTOo0E1UAX1+eBmuAmc\/eBq0\r\nFjjmMyPZy7EhElAUa2sqw5QS2\/AK34P0rccCaJerRJ0mU54neL5qSEuuPQnVcn\/\/\r\n3LGndYF8t5kHI3iXV3TJ2vyagUkWeDl6z9pyW0Y=\r\n-----END CERTIFICATE-----" +} \ No newline at end of file diff --git a/files_reader/vendor/bitjs/archive/rarvm.js b/files_reader/vendor/bitjs/archive/rarvm.js index 130e543..98a1cb8 100644 --- a/files_reader/vendor/bitjs/archive/rarvm.js +++ b/files_reader/vendor/bitjs/archive/rarvm.js @@ -11,6 +11,36 @@ */ const CRCTab = new Array(256).fill(0); +// Helper functions between signed and unsigned integers. + +/** + * -1 becomes 0xffffffff + */ +function fromSigned32ToUnsigned32(val) { + return (val < 0) ? (val += 0x100000000) : val; +} + +/** + * 0xffffffff becomes -1 + */ +function fromUnsigned32ToSigned32(val) { + return (val >= 0x80000000) ? (val -= 0x100000000) : val; +} + +/** + * -1 becomes 0xff + */ +function fromSigned8ToUnsigned8(val) { + return (val < 0) ? (val += 0x100) : val; +} + +/** + * 0xff becomes -1 + */ +function fromUnsigned8ToSigned8(val) { + return (val >= 0x80) ? (val -= 0x100) : val; +} + function InitCRC() { for (let i = 0; i < 256; ++i) { let c = i; @@ -635,6 +665,105 @@ class RarVM { break; } + + // The C++ version of this standard filter uses an odd mixture of + // signed and unsigned integers, bytes and various casts. Careful! + case VM_StandardFilters.VMSF_AUDIO: { + const dataSize = this.R_[4]; + const channels = this.R_[0]; + let srcOffset = 0; + let destOffset = dataSize; + + //SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize); + const dataView = new DataView(this.mem_.buffer, VM_GLOBALMEMADDR); + dataView.setUint32(0x20 /* byte offset */, + dataSize /* value */, + true /* little endian */); + + if (dataSize >= VM_GLOBALMEMADDR / 2) { + break; + } + + for (let curChannel = 0; curChannel < channels; ++curChannel) { + let prevByte = 0; // uint + let prevDelta = 0; // uint + let dif = [0, 0, 0, 0, 0, 0, 0]; + let d1 = 0, d2 = 0, d3; // ints + let k1 = 0, k2 = 0, k3 = 0; // ints + + for (var i = curChannel, byteCount = 0; + i < dataSize; + i += channels, ++byteCount) { + d3 = d2; + d2 = fromUnsigned32ToSigned32(prevDelta - d1); + d1 = fromUnsigned32ToSigned32(prevDelta); + + let predicted = fromSigned32ToUnsigned32(8*prevByte + k1*d1 + k2*d2 + k3*d3); // uint + predicted = (predicted >>> 3) & 0xff; + + let curByte = this.mem_[srcOffset++]; // uint + + // Predicted-=CurByte; + predicted = fromSigned32ToUnsigned32(predicted - curByte); + this.mem_[destOffset + i] = (predicted & 0xff); + + // PrevDelta=(signed char)(Predicted-PrevByte); + // where Predicted, PrevByte, PrevDelta are all unsigned int (32) + // casting this subtraction to a (signed char) is kind of invalid + // but it does the following: + // - do the subtraction + // - get the bottom 8 bits of the result + // - if it was >= 0x80, then the value is negative (subtract 0x100) + // - if the value is now negative, add 0x100000000 to make unsigned + // + // Example: + // predicted = 101 + // prevByte = 4294967158 + // (predicted - prevByte) = -4294967057 + // take lower 8 bits: 1110 1111 = 239 + // since > 127, subtract 256 = -17 + // since < 0, add 0x100000000 = 4294967279 + prevDelta = fromSigned32ToUnsigned32( + fromUnsigned8ToSigned8((predicted - prevByte) & 0xff)); + prevByte = predicted; + + // int D=((signed char)CurByte)<<3; + let curByteAsSignedChar = fromUnsigned8ToSigned8(curByte); // signed char + let d = (curByteAsSignedChar << 3); + + dif[0] += Math.abs(d); + dif[1] += Math.abs(d-d1); + dif[2] += Math.abs(d+d1); + dif[3] += Math.abs(d-d2); + dif[4] += Math.abs(d+d2); + dif[5] += Math.abs(d-d3); + dif[6] += Math.abs(d+d3); + + if ((byteCount & 0x1f) == 0) { + let minDif = dif[0], numMinDif = 0; + dif[0] = 0; + for (let j = 1; j < 7; ++j) { + if (dif[j] < minDif) { + minDif = dif[j]; + numMinDif = j; + } + dif[j] = 0; + } + switch (numMinDif) { + case 1: if (k1>=-16) k1--; break; + case 2: if (k1 < 16) k1++; break; + case 3: if (k2>=-16) k2--; break; + case 4: if (k2 < 16) k2++; break; + case 5: if (k3>=-16) k3--; break; + case 6: if (k3 < 16) k3++; break; + } + } + } + } + + break; + } + case VM_StandardFilters.VMSF_DELTA: { const dataSize = this.R_[4]; const channels = this.R_[0]; diff --git a/files_reader/vendor/bitjs/archive/unrar.js b/files_reader/vendor/bitjs/archive/unrar.js index fe38936..fcad87e 100644 --- a/files_reader/vendor/bitjs/archive/unrar.js +++ b/files_reader/vendor/bitjs/archive/unrar.js @@ -8,1582 +8,11 @@ */ // This file expects to be invoked as a Worker (see onmessage below). -// ... -// ... but importScripts does not work when CSP2 nonce is active, so inline these instead... -//importScripts('../io/bitstream.js'); -// +importScripts('../io/bitstream.js'); +importScripts('../io/bytebuffer.js'); +importScripts('archive.js'); +importScripts('rarvm.js'); -/* - * bitstream.js - * - * Provides readers for bitstreams. - * - * Licensed under the MIT License - * - * Copyright(c) 2011 Google Inc. - * Copyright(c) 2011 antimatter15 - */ - -var bitjs = bitjs || {}; -bitjs.io = bitjs.io || {}; - - -/** - * This bit stream peeks and consumes bits out of a binary stream. - */ -bitjs.io.BitStream = class { - /** - * @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array. - * @param {boolean} rtl Whether the stream reads bits from the byte starting - * from bit 7 to 0 (true) or bit 0 to 7 (false). - * @param {Number} opt_offset The offset into the ArrayBuffer - * @param {Number} opt_length The length of this BitStream - */ - constructor(ab, rtl, opt_offset, opt_length) { - if (!ab || !ab.toString || ab.toString() !== "[object ArrayBuffer]") { - throw "Error! BitArray constructed with an invalid ArrayBuffer object"; - } - - const offset = opt_offset || 0; - const length = opt_length || ab.byteLength; - this.bytes = new Uint8Array(ab, offset, length); - this.bytePtr = 0; // tracks which byte we are on - this.bitPtr = 0; // tracks which bit we are on (can have values 0 through 7) - this.peekBits = rtl ? this.peekBits_rtl : this.peekBits_ltr; - } - - /** - * byte0 byte1 byte2 byte3 - * 7......0 | 7......0 | 7......0 | 7......0 - * - * The bit pointer starts at bit0 of byte0 and moves left until it reaches - * bit7 of byte0, then jumps to bit0 of byte1, etc. - * @param {number} n The number of bits to peek. - * @param {boolean=} movePointers Whether to move the pointer, defaults false. - * @return {number} The peeked bits, as an unsigned number. - */ - peekBits_ltr(n, opt_movePointers) { - if (n <= 0 || typeof n != typeof 1) { - return 0; - } - - const movePointers = opt_movePointers || false; - const bytes = this.bytes; - let bytePtr = this.bytePtr; - let bitPtr = this.bitPtr; - let result = 0; - let bitsIn = 0; - - // keep going until we have no more bits left to peek at - // TODO: Consider putting all bits from bytes we will need into a variable and then - // shifting/masking it to just extract the bits we want. - // This could be considerably faster when reading more than 3 or 4 bits at a time. - while (n > 0) { - if (bytePtr >= bytes.length) { - throw "Error! Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + - bytes.length + ", bitPtr=" + bitPtr; - return -1; - } - - const numBitsLeftInThisByte = (8 - bitPtr); - if (n >= numBitsLeftInThisByte) { - const mask = (bitjs.io.BitStream.BITMASK[numBitsLeftInThisByte] << bitPtr); - result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); - - bytePtr++; - bitPtr = 0; - bitsIn += numBitsLeftInThisByte; - n -= numBitsLeftInThisByte; - } - else { - const mask = (bitjs.io.BitStream.BITMASK[n] << bitPtr); - result |= (((bytes[bytePtr] & mask) >> bitPtr) << bitsIn); - - bitPtr += n; - bitsIn += n; - n = 0; - } - } - - if (movePointers) { - this.bitPtr = bitPtr; - this.bytePtr = bytePtr; - } - - return result; - } - - /** - * byte0 byte1 byte2 byte3 - * 7......0 | 7......0 | 7......0 | 7......0 - * - * The bit pointer starts at bit7 of byte0 and moves right until it reaches - * bit0 of byte0, then goes to bit7 of byte1, etc. - * @param {number} n The number of bits to peek. - * @param {boolean=} movePointers Whether to move the pointer, defaults false. - * @return {number} The peeked bits, as an unsigned number. - */ - peekBits_rtl(n, opt_movePointers) { - if (n <= 0 || typeof n != typeof 1) { - return 0; - } - - const movePointers = opt_movePointers || false; - const bytes = this.bytes; - let bytePtr = this.bytePtr; - let bitPtr = this.bitPtr; - let result = 0; - - // keep going until we have no more bits left to peek at - // TODO: Consider putting all bits from bytes we will need into a variable and then - // shifting/masking it to just extract the bits we want. - // This could be considerably faster when reading more than 3 or 4 bits at a time. - while (n > 0) { - if (bytePtr >= bytes.length) { - throw "Error! Overflowed the bit stream! n=" + n + ", bytePtr=" + bytePtr + ", bytes.length=" + - bytes.length + ", bitPtr=" + bitPtr; - return -1; - } - - const numBitsLeftInThisByte = (8 - bitPtr); - if (n >= numBitsLeftInThisByte) { - result <<= numBitsLeftInThisByte; - result |= (bitjs.io.BitStream.BITMASK[numBitsLeftInThisByte] & bytes[bytePtr]); - bytePtr++; - bitPtr = 0; - n -= numBitsLeftInThisByte; - } - else { - result <<= n; - result |= ((bytes[bytePtr] & (bitjs.io.BitStream.BITMASK[n] << (8 - n - bitPtr))) >> (8 - n - bitPtr)); - - bitPtr += n; - n = 0; - } - } - - if (movePointers) { - this.bitPtr = bitPtr; - this.bytePtr = bytePtr; - } - - return result; - } - - /** - * Peek at 16 bits from current position in the buffer. - * Bit at (bytePtr,bitPtr) has the highest position in returning data. - * Taken from getbits.hpp in unrar. - * TODO: Move this out of BitStream and into unrar. - */ - getBits() { - return (((((this.bytes[this.bytePtr] & 0xff) << 16) + - ((this.bytes[this.bytePtr+1] & 0xff) << 8) + - ((this.bytes[this.bytePtr+2] & 0xff))) >>> (8-this.bitPtr)) & 0xffff); - } - - /** - * Reads n bits out of the stream, consuming them (moving the bit pointer). - * @param {number} n The number of bits to read. - * @return {number} The read bits, as an unsigned number. - */ - readBits(n) { - return this.peekBits(n, true); - } - - /** - * This returns n bytes as a sub-array, advancing the pointer if movePointers - * is true. Only use this for uncompressed blocks as this throws away remaining - * bits in the current byte. - * @param {number} n The number of bytes to peek. - * @param {boolean=} movePointers Whether to move the pointer, defaults false. - * @return {Uint8Array} The subarray. - */ - peekBytes(n, opt_movePointers) { - if (n <= 0 || typeof n != typeof 1) { - return 0; - } - - // from http://tools.ietf.org/html/rfc1951#page-11 - // "Any bits of input up to the next byte boundary are ignored." - while (this.bitPtr != 0) { - this.readBits(1); - } - - const movePointers = opt_movePointers || false; - let bytePtr = this.bytePtr; - let bitPtr = this.bitPtr; - - const result = this.bytes.subarray(bytePtr, bytePtr + n); - - if (movePointers) { - this.bytePtr += n; - } - - return result; - } - - /** - * @param {number} n The number of bytes to read. - * @return {Uint8Array} The subarray. - */ - readBytes(n) { - return this.peekBytes(n, true); - } -} - -// mask for getting N number of bits (0-8) -bitjs.io.BitStream.BITMASK = [0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF ]; - -//importScripts('../io/bytebuffer.js'); -// - -/* - * bytestream.js - * - * Provides a writer for bytes. - * - * Licensed under the MIT License - * - * Copyright(c) 2011 Google Inc. - * Copyright(c) 2011 antimatter15 - */ - -var bitjs = bitjs || {}; -bitjs.io = bitjs.io || {}; - - -/** - * A write-only Byte buffer which uses a Uint8 Typed Array as a backing store. - */ -bitjs.io.ByteBuffer = class { - /** - * @param {number} numBytes The number of bytes to allocate. - */ - constructor(numBytes) { - if (typeof numBytes != typeof 1 || numBytes <= 0) { - throw "Error! ByteBuffer initialized with '" + numBytes + "'"; - } - this.data = new Uint8Array(numBytes); - this.ptr = 0; - } - - - /** - * @param {number} b The byte to insert. - */ - insertByte(b) { - // TODO: throw if byte is invalid? - this.data[this.ptr++] = b; - } - - /** - * @param {Array.|Uint8Array|Int8Array} bytes The bytes to insert. - */ - insertBytes(bytes) { - // TODO: throw if bytes is invalid? - this.data.set(bytes, this.ptr); - this.ptr += bytes.length; - } - - /** - * Writes an unsigned number into the next n bytes. If the number is too large - * to fit into n bytes or is negative, an error is thrown. - * @param {number} num The unsigned number to write. - * @param {number} numBytes The number of bytes to write the number into. - */ - writeNumber(num, numBytes) { - if (numBytes < 1) { - throw 'Trying to write into too few bytes: ' + numBytes; - } - if (num < 0) { - throw 'Trying to write a negative number (' + num + - ') as an unsigned number to an ArrayBuffer'; - } - if (num > (Math.pow(2, numBytes * 8) - 1)) { - throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; - } - - // Roll 8-bits at a time into an array of bytes. - const bytes = []; - while (numBytes-- > 0) { - const eightBits = num & 255; - bytes.push(eightBits); - num >>= 8; - } - - this.insertBytes(bytes); - } - - /** - * Writes a signed number into the next n bytes. If the number is too large - * to fit into n bytes, an error is thrown. - * @param {number} num The signed number to write. - * @param {number} numBytes The number of bytes to write the number into. - */ - writeSignedNumber(num, numBytes) { - if (numBytes < 1) { - throw 'Trying to write into too few bytes: ' + numBytes; - } - - const HALF = Math.pow(2, (numBytes * 8) - 1); - if (num >= HALF || num < -HALF) { - throw 'Trying to write ' + num + ' into only ' + numBytes + ' bytes'; - } - - // Roll 8-bits at a time into an array of bytes. - const bytes = []; - while (numBytes-- > 0) { - const eightBits = num & 255; - bytes.push(eightBits); - num >>= 8; - } - - this.insertBytes(bytes); - } - - /** - * @param {string} str The ASCII string to write. - */ - writeASCIIString(str) { - for (let i = 0; i < str.length; ++i) { - const curByte = str.charCodeAt(i); - if (curByte < 0 || curByte > 255) { - throw 'Trying to write a non-ASCII string!'; - } - this.insertByte(curByte); - } - }; -} - -//importScripts('archive.js'); -// - -/** - * archive.js - * - * Provides base functionality for unarchiving. - * - * Licensed under the MIT License - * - * Copyright(c) 2011 Google Inc. - */ - -var bitjs = bitjs || {}; -bitjs.archive = bitjs.archive || {}; - -/** - * An unarchive event. - */ -bitjs.archive.UnarchiveEvent = class { - /** - * @param {string} type The event type. - */ - constructor(type) { - /** - * The event type. - * @type {string} - */ - this.type = type; - } -} - -/** - * The UnarchiveEvent types. - */ -bitjs.archive.UnarchiveEvent.Type = { - START: 'start', - PROGRESS: 'progress', - EXTRACT: 'extract', - FINISH: 'finish', - INFO: 'info', - ERROR: 'error' -}; - -/** - * Useful for passing info up to the client (for debugging). - */ -bitjs.archive.UnarchiveInfoEvent = class extends bitjs.archive.UnarchiveEvent { - /** - * @param {string} msg The info message. - */ - constructor(msg) { - super(bitjs.archive.UnarchiveEvent.Type.INFO); - - /** - * The information message. - * @type {string} - */ - this.msg = msg; - } -} - -/** - * An unrecoverable error has occured. - */ -bitjs.archive.UnarchiveErrorEvent = class extends bitjs.archive.UnarchiveEvent { - /** - * @param {string} msg The error message. - */ - constructor(msg) { - super(bitjs.archive.UnarchiveEvent.Type.ERROR); - - /** - * The information message. - * @type {string} - */ - this.msg = msg; - } -} - -/** - * Start event. - */ -bitjs.archive.UnarchiveStartEvent = class extends bitjs.archive.UnarchiveEvent { - constructor() { - super(bitjs.archive.UnarchiveEvent.Type.START); - } -} - -/** - * Finish event. - */ -bitjs.archive.UnarchiveFinishEvent = class extends bitjs.archive.UnarchiveEvent { - constructor() { - super(bitjs.archive.UnarchiveEvent.Type.FINISH); - } -} - -/** - * Progress event. - */ -bitjs.archive.UnarchiveProgressEvent = class extends bitjs.archive.UnarchiveEvent { - /** - * @param {string} currentFilename - * @param {number} currentFileNumber - * @param {number} currentBytesUnarchivedInFile - * @param {number} currentBytesUnarchived - * @param {number} totalUncompressedBytesInArchive - * @param {number} totalFilesInArchive - */ - constructor(currentFilename, currentFileNumber, currentBytesUnarchivedInFile, - currentBytesUnarchived, totalUncompressedBytesInArchive, totalFilesInArchive) { - super(bitjs.archive.UnarchiveEvent.Type.PROGRESS); - - this.currentFilename = currentFilename; - this.currentFileNumber = currentFileNumber; - this.currentBytesUnarchivedInFile = currentBytesUnarchivedInFile; - this.totalFilesInArchive = totalFilesInArchive; - this.currentBytesUnarchived = currentBytesUnarchived; - this.totalUncompressedBytesInArchive = totalUncompressedBytesInArchive; - } -} - -/** - * Extract event. - */ -bitjs.archive.UnarchiveExtractEvent = class extends bitjs.archive.UnarchiveEvent { - /** - * @param {UnarchivedFile} unarchivedFile - */ - constructor(unarchivedFile) { - super(bitjs.archive.UnarchiveEvent.Type.EXTRACT); - - /** - * @type {UnarchivedFile} - */ - this.unarchivedFile = unarchivedFile; - } -} - -/** - * All extracted files returned by an Unarchiver will implement - * the following interface: - * - * interface UnarchivedFile { - * string filename - * TypedArray fileData - * } - * - */ - -/** - * Base class for all Unarchivers. - */ -bitjs.archive.Unarchiver = class { - /** - * @param {ArrayBuffer} arrayBuffer The Array Buffer. - * @param {string} opt_pathToBitJS Optional string for where the BitJS files are located. - */ - constructor(arrayBuffer, opt_pathToBitJS) { - /** - * The ArrayBuffer object. - * @type {ArrayBuffer} - * @protected - */ - this.ab = arrayBuffer; - - /** - * The path to the BitJS files. - * @type {string} - * @private - */ - this.pathToBitJS_ = opt_pathToBitJS || '/'; - - /** - * A map from event type to an array of listeners. - * @type {Map.} - */ - this.listeners_ = {}; - for (let type in bitjs.archive.UnarchiveEvent.Type) { - this.listeners_[bitjs.archive.UnarchiveEvent.Type[type]] = []; - } - - /** - * Private web worker initialized during start(). - * @type {Worker} - * @private - */ - this.worker_ = null; - } - - /** - * This method must be overridden by the subclass to return the script filename. - * @return {string} The script filename. - * @protected. - */ - getScriptFileName() { - throw 'Subclasses of AbstractUnarchiver must overload getScriptFileName()'; - } - - /** - * Adds an event listener for UnarchiveEvents. - * - * @param {string} Event type. - * @param {function} An event handler function. - */ - addEventListener(type, listener) { - if (type in this.listeners_) { - if (this.listeners_[type].indexOf(listener) == -1) { - this.listeners_[type].push(listener); - } - } - } - - /** - * Removes an event listener. - * - * @param {string} Event type. - * @param {EventListener|function} An event listener or handler function. - */ - removeEventListener(type, listener) { - if (type in this.listeners_) { - const index = this.listeners_[type].indexOf(listener); - if (index != -1) { - this.listeners_[type].splice(index, 1); - } - } - } - - /** - * Receive an event and pass it to the listener functions. - * - * @param {bitjs.archive.UnarchiveEvent} e - * @private - */ - handleWorkerEvent_(e) { - if ((e instanceof bitjs.archive.UnarchiveEvent || e.type) && - this.listeners_[e.type] instanceof Array) { - this.listeners_[e.type].forEach(function (listener) { listener(e) }); - if (e.type == bitjs.archive.UnarchiveEvent.Type.FINISH) { - this.worker_.terminate(); - } - } else { - console.log(e); - } - } - - /** - * Starts the unarchive in a separate Web Worker thread and returns immediately. - */ - start() { - const me = this; - const scriptFileName = this.pathToBitJS_ + this.getScriptFileName(); - if (scriptFileName) { - this.worker_ = new Worker(scriptFileName); - - this.worker_.onerror = function(e) { - console.log('Worker error: message = ' + e.message); - throw e; - }; - - this.worker_.onmessage = function(e) { - if (typeof e.data == 'string') { - // Just log any strings the workers pump our way. - console.log(e.data); - } else { - // Assume that it is an UnarchiveEvent. Some browsers preserve the 'type' - // so that instanceof UnarchiveEvent returns true, but others do not. - me.handleWorkerEvent_(e.data); - } - }; - - this.worker_.postMessage({file: this.ab}); - } - } - - /** - * Terminates the Web Worker for this Unarchiver and returns immediately. - */ - stop() { - if (this.worker_) { - this.worker_.terminate(); - } - } -} - - -/** - * Unzipper - */ -bitjs.archive.Unzipper = class extends bitjs.archive.Unarchiver { - constructor(arrayBuffer, opt_pathToBitJS) { - super(arrayBuffer, opt_pathToBitJS); - } - - getScriptFileName() { return 'archive/unzip.js'; } -} - - -/** - * Unrarrer - */ -bitjs.archive.Unrarrer = class extends bitjs.archive.Unarchiver { - constructor(arrayBuffer, opt_pathToBitJS) { - super(arrayBuffer, opt_pathToBitJS); - } - - getScriptFileName() { return 'archive/unrar.js'; } -} - -/** - * Untarrer - * @extends {bitjs.archive.Unarchiver} - * @constructor - */ -bitjs.archive.Untarrer = class extends bitjs.archive.Unarchiver { - constructor(arrayBuffer, opt_pathToBitJS) { - super(arrayBuffer, opt_pathToBitJS); - } - - getScriptFileName() { return 'archive/untar.js'; }; -} - -/** - * Factory method that creates an unarchiver based on the byte signature found - * in the arrayBuffer. - * @param {ArrayBuffer} ab - * @param {string=} opt_pathToBitJS Path to the unarchiver script files. - * @return {bitjs.archive.Unarchiver} - */ -bitjs.archive.GetUnarchiver = function(ab, opt_pathToBitJS) { - let unarchiver = null; - const pathToBitJS = opt_pathToBitJS || ''; - const h = new Uint8Array(ab, 0, 10); - - if (h[0] == 0x52 && h[1] == 0x61 && h[2] == 0x72 && h[3] == 0x21) { // Rar! - unarchiver = new bitjs.archive.Unrarrer(ab, pathToBitJS); - } else if (h[0] == 0x50 && h[1] == 0x4B) { // PK (Zip) - unarchiver = new bitjs.archive.Unzipper(ab, pathToBitJS); - } else { // Try with tar - unarchiver = new bitjs.archive.Untarrer(ab, pathToBitJS); - } - return unarchiver; -}; - -//importScripts('rarvm.js'); -// - -/** - * rarvm.js - * - * Licensed under the MIT License - * - * Copyright(c) 2017 Google Inc. - */ - -/** - * CRC Implementation. - */ -const CRCTab = new Array(256).fill(0); - -function InitCRC() { - for (let i = 0; i < 256; ++i) { - let c = i; - for (let j = 0; j < 8; ++j) { - // Read http://stackoverflow.com/questions/6798111/bitwise-operations-on-32-bit-unsigned-ints - // for the bitwise operator issue (JS interprets operands as 32-bit signed - // integers and we need to deal with unsigned ones here). - c = ((c & 1) ? ((c >>> 1) ^ 0xEDB88320) : (c >>> 1)) >>> 0; - } - CRCTab[i] = c; - } -} - -/** - * @param {number} startCRC - * @param {Uint8Array} arr - * @return {number} - */ -function CRC(startCRC, arr) { - if (CRCTab[1] == 0) { - InitCRC(); - } - -/* -#if defined(LITTLE_ENDIAN) && defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT) - while (Size>0 && ((long)Data & 7)) - { - StartCRC=CRCTab[(byte)(StartCRC^Data[0])]^(StartCRC>>8); - Size--; - Data++; - } - while (Size>=8) - { - StartCRC^=*(uint32 *)Data; - StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); - StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); - StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); - StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); - StartCRC^=*(uint32 *)(Data+4); - StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); - StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); - StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); - StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8); - Data+=8; - Size-=8; - } -#endif -*/ - - for (let i = 0; i < arr.length; ++i) { - const byte = ((startCRC ^ arr[i]) >>> 0) & 0xff; - startCRC = (CRCTab[byte] ^ (startCRC >>> 8)) >>> 0; - } - - return startCRC; -} - -// ============================================================================================== // - - -/** - * RarVM Implementation. - */ -const VM_MEMSIZE = 0x40000; -const VM_MEMMASK = (VM_MEMSIZE - 1); -const VM_GLOBALMEMADDR = 0x3C000; -const VM_GLOBALMEMSIZE = 0x2000; -const VM_FIXEDGLOBALSIZE = 64; -const MAXWINSIZE = 0x400000; -const MAXWINMASK = (MAXWINSIZE - 1); - -/** - */ -const VM_Commands = { - VM_MOV: 0, - VM_CMP: 1, - VM_ADD: 2, - VM_SUB: 3, - VM_JZ: 4, - VM_JNZ: 5, - VM_INC: 6, - VM_DEC: 7, - VM_JMP: 8, - VM_XOR: 9, - VM_AND: 10, - VM_OR: 11, - VM_TEST: 12, - VM_JS: 13, - VM_JNS: 14, - VM_JB: 15, - VM_JBE: 16, - VM_JA: 17, - VM_JAE: 18, - VM_PUSH: 19, - VM_POP: 20, - VM_CALL: 21, - VM_RET: 22, - VM_NOT: 23, - VM_SHL: 24, - VM_SHR: 25, - VM_SAR: 26, - VM_NEG: 27, - VM_PUSHA: 28, - VM_POPA: 29, - VM_PUSHF: 30, - VM_POPF: 31, - VM_MOVZX: 32, - VM_MOVSX: 33, - VM_XCHG: 34, - VM_MUL: 35, - VM_DIV: 36, - VM_ADC: 37, - VM_SBB: 38, - VM_PRINT: 39, - -/* -#ifdef VM_OPTIMIZE - VM_MOVB, VM_MOVD, VM_CMPB, VM_CMPD, - - VM_ADDB, VM_ADDD, VM_SUBB, VM_SUBD, VM_INCB, VM_INCD, VM_DECB, VM_DECD, - VM_NEGB, VM_NEGD, -#endif -*/ - - // TODO: This enum value would be much larger if VM_OPTIMIZE. - VM_STANDARD: 40, -}; - -/** - */ -const VM_StandardFilters = { - VMSF_NONE: 0, - VMSF_E8: 1, - VMSF_E8E9: 2, - VMSF_ITANIUM: 3, - VMSF_RGB: 4, - VMSF_AUDIO: 5, - VMSF_DELTA: 6, - VMSF_UPCASE: 7, -}; - -/** - */ -const VM_Flags = { - VM_FC: 1, - VM_FZ: 2, - VM_FS: 0x80000000, -}; - -/** - */ -const VM_OpType = { - VM_OPREG: 0, - VM_OPINT: 1, - VM_OPREGMEM: 2, - VM_OPNONE: 3, -}; - -/** - * Finds the key that maps to a given value in an object. This function is useful in debugging - * variables that use the above enums. - * @param {Object} obj - * @param {number} val - * @return {string} The key/enum value as a string. - */ -function findKeyForValue(obj, val) { - for (let key in obj) { - if (obj[key] === val) { - return key; - } - } - return null; -} - -function getDebugString(obj, val) { - let s = 'Unknown.'; - if (obj === VM_Commands) { - s = 'VM_Commands.'; - } else if (obj === VM_StandardFilters) { - s = 'VM_StandardFilters.'; - } else if (obj === VM_Flags) { - s = 'VM_OpType.'; - } else if (obj === VM_OpType) { - s = 'VM_OpType.'; - } - - return s + findKeyForValue(obj, val); -} - -/** - */ -class VM_PreparedOperand { - constructor() { - /** @type {VM_OpType} */ - this.Type; - - /** @type {number} */ - this.Data = 0; - - /** @type {number} */ - this.Base = 0; - - // TODO: In C++ this is a uint* - /** @type {Array} */ - this.Addr = null; - }; - - /** @return {string} */ - toString() { - if (this.Type === null) { - return 'Error: Type was null in VM_PreparedOperand'; - } - return '{ ' - + 'Type: ' + getDebugString(VM_OpType, this.Type) - + ', Data: ' + this.Data - + ', Base: ' + this.Base - + ' }'; - } -} - -/** - */ -class VM_PreparedCommand { - constructor() { - /** @type {VM_Commands} */ - this.OpCode; - - /** @type {boolean} */ - this.ByteMode = false; - - /** @type {VM_PreparedOperand} */ - this.Op1 = new VM_PreparedOperand(); - - /** @type {VM_PreparedOperand} */ - this.Op2 = new VM_PreparedOperand(); - } - - /** @return {string} */ - toString(indent) { - if (this.OpCode === null) { - return 'Error: OpCode was null in VM_PreparedCommand'; - } - indent = indent || ''; - return indent + '{\n' - + indent + ' OpCode: ' + getDebugString(VM_Commands, this.OpCode) + ',\n' - + indent + ' ByteMode: ' + this.ByteMode + ',\n' - + indent + ' Op1: ' + this.Op1.toString() + ',\n' - + indent + ' Op2: ' + this.Op2.toString() + ',\n' - + indent + '}'; - } -} - -/** - */ -class VM_PreparedProgram { - constructor() { - /** @type {Array} */ - this.Cmd = []; - - /** @type {Array} */ - this.AltCmd = null; - - /** @type {Uint8Array} */ - this.GlobalData = new Uint8Array(); - - /** @type {Uint8Array} */ - this.StaticData = new Uint8Array(); // static data contained in DB operators - - /** @type {Uint32Array} */ - this.InitR = new Uint32Array(7); - - /** - * A pointer to bytes that have been filtered by a program. - * @type {Uint8Array} - */ - this.FilteredData = null; - } - - /** @return {string} */ - toString() { - let s = '{\n Cmd: [\n'; - for (let i = 0; i < this.Cmd.length; ++i) { - s += this.Cmd[i].toString(' ') + ',\n'; - } - s += '],\n'; - // TODO: Dump GlobalData, StaticData, InitR? - s += ' }\n'; - return s; - } -} - -/** - */ -class UnpackFilter { - constructor() { - /** @type {number} */ - this.BlockStart = 0; - - /** @type {number} */ - this.BlockLength = 0; - - /** @type {number} */ - this.ExecCount = 0; - - /** @type {boolean} */ - this.NextWindow = false; - - // position of parent filter in Filters array used as prototype for filter - // in PrgStack array. Not defined for filters in Filters array. - /** @type {number} */ - this.ParentFilter = null; - - /** @type {VM_PreparedProgram} */ - this.Prg = new VM_PreparedProgram(); - } -} - -const VMCF_OP0 = 0; -const VMCF_OP1 = 1; -const VMCF_OP2 = 2; -const VMCF_OPMASK = 3; -const VMCF_BYTEMODE = 4; -const VMCF_JUMP = 8; -const VMCF_PROC = 16; -const VMCF_USEFLAGS = 32; -const VMCF_CHFLAGS = 64; - -const VM_CmdFlags = [ - /* VM_MOV */ VMCF_OP2 | VMCF_BYTEMODE , - /* VM_CMP */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_ADD */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_SUB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_JZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , - /* VM_JNZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , - /* VM_INC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_DEC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_JMP */ VMCF_OP1 | VMCF_JUMP , - /* VM_XOR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_AND */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_OR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_TEST */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_JS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , - /* VM_JNS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , - /* VM_JB */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , - /* VM_JBE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , - /* VM_JA */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , - /* VM_JAE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS , - /* VM_PUSH */ VMCF_OP1 , - /* VM_POP */ VMCF_OP1 , - /* VM_CALL */ VMCF_OP1 | VMCF_PROC , - /* VM_RET */ VMCF_OP0 | VMCF_PROC , - /* VM_NOT */ VMCF_OP1 | VMCF_BYTEMODE , - /* VM_SHL */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_SHR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_SAR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_NEG */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS , - /* VM_PUSHA */ VMCF_OP0 , - /* VM_POPA */ VMCF_OP0 , - /* VM_PUSHF */ VMCF_OP0 | VMCF_USEFLAGS , - /* VM_POPF */ VMCF_OP0 | VMCF_CHFLAGS , - /* VM_MOVZX */ VMCF_OP2 , - /* VM_MOVSX */ VMCF_OP2 , - /* VM_XCHG */ VMCF_OP2 | VMCF_BYTEMODE , - /* VM_MUL */ VMCF_OP2 | VMCF_BYTEMODE , - /* VM_DIV */ VMCF_OP2 | VMCF_BYTEMODE , - /* VM_ADC */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS , - /* VM_SBB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS , - /* VM_PRINT */ VMCF_OP0 , -]; - - -/** - */ -class StandardFilterSignature { - /** - * @param {number} length - * @param {number} crc - * @param {VM_StandardFilters} type - */ - constructor(length, crc, type) { - /** @type {number} */ - this.Length = length; - - /** @type {number} */ - this.CRC = crc; - - /** @type {VM_StandardFilters} */ - this.Type = type; - } -} - -/** - * @type {Array} - */ -const StdList = [ - new StandardFilterSignature(53, 0xad576887, VM_StandardFilters.VMSF_E8), - new StandardFilterSignature(57, 0x3cd7e57e, VM_StandardFilters.VMSF_E8E9), - new StandardFilterSignature(120, 0x3769893f, VM_StandardFilters.VMSF_ITANIUM), - new StandardFilterSignature(29, 0x0e06077d, VM_StandardFilters.VMSF_DELTA), - new StandardFilterSignature(149, 0x1c2c5dc8, VM_StandardFilters.VMSF_RGB), - new StandardFilterSignature(216, 0xbc85e701, VM_StandardFilters.VMSF_AUDIO), - new StandardFilterSignature(40, 0x46b9c560, VM_StandardFilters.VMSF_UPCASE), -]; - -/** - * @constructor - */ -class RarVM { - constructor() { - /** @private {Uint8Array} */ - this.mem_ = null; - - /** @private {Uint32Array} */ - this.R_ = new Uint32Array(8); - - /** @private {number} */ - this.flags_ = 0; - } - - /** - * Initializes the memory of the VM. - */ - init() { - if (!this.mem_) { - this.mem_ = new Uint8Array(VM_MEMSIZE); - } - } - - /** - * @param {Uint8Array} code - * @return {VM_StandardFilters} - */ - isStandardFilter(code) { - const codeCRC = (CRC(0xffffffff, code, code.length) ^ 0xffffffff) >>> 0; - for (let i = 0; i < StdList.length; ++i) { - if (StdList[i].CRC == codeCRC && StdList[i].Length == code.length) - return StdList[i].Type; - } - - return VM_StandardFilters.VMSF_NONE; - } - - /** - * @param {VM_PreparedOperand} op - * @param {boolean} byteMode - * @param {bitjs.io.BitStream} bstream A rtl bit stream. - */ - decodeArg(op, byteMode, bstream) { - const data = bstream.peekBits(16); - if (data & 0x8000) { - op.Type = VM_OpType.VM_OPREG; // Operand is register (R[0]..R[7]) - bstream.readBits(1); // 1 flag bit and... - op.Data = bstream.readBits(3); // ... 3 register number bits - op.Addr = [this.R_[op.Data]] // TODO &R[Op.Data] // Register address - } else { - if ((data & 0xc000) == 0) { - op.Type = VM_OpType.VM_OPINT; // Operand is integer - bstream.readBits(2); // 2 flag bits - if (byteMode) { - op.Data = bstream.readBits(8); // Byte integer. - } else { - op.Data = RarVM.readData(bstream); // 32 bit integer. - } - } else { - // Operand is data addressed by register data, base address or both. - op.Type = VM_OpType.VM_OPREGMEM; - if ((data & 0x2000) == 0) { - bstream.readBits(3); // 3 flag bits - // Base address is zero, just use the address from register. - op.Data = bstream.readBits(3); // (Data>>10)&7 - op.Addr = [this.R_[op.Data]]; // TODO &R[op.Data] - op.Base = 0; - } else { - bstream.readBits(4); // 4 flag bits - if ((data & 0x1000) == 0) { - // Use both register and base address. - op.Data = bstream.readBits(3); - op.Addr = [this.R_[op.Data]]; // TODO &R[op.Data] - } else { - // Use base address only. Access memory by fixed address. - op.Data = 0; - } - op.Base = RarVM.readData(bstream); // Read base address. - } - } - } - } - - /** - * @param {VM_PreparedProgram} prg - */ - execute(prg) { - this.R_.set(prg.InitR); - - const globalSize = Math.min(prg.GlobalData.length, VM_GLOBALMEMSIZE); - if (globalSize) { - this.mem_.set(prg.GlobalData.subarray(0, globalSize), VM_GLOBALMEMADDR); - } - - const staticSize = Math.min(prg.StaticData.length, VM_GLOBALMEMSIZE - globalSize); - if (staticSize) { - this.mem_.set(prg.StaticData.subarray(0, staticSize), VM_GLOBALMEMADDR + globalSize); - } - - this.R_[7] = VM_MEMSIZE; - this.flags_ = 0; - - const preparedCodes = prg.AltCmd ? prg.AltCmd : prg.Cmd; - if (prg.Cmd.length > 0 && !this.executeCode(preparedCodes)) { - // Invalid VM program. Let's replace it with 'return' command. - preparedCode.OpCode = VM_Commands.VM_RET; - } - - const dataView = new DataView(this.mem_.buffer, VM_GLOBALMEMADDR); - let newBlockPos = dataView.getUint32(0x20, true /* little endian */) & VM_MEMMASK; - const newBlockSize = dataView.getUint32(0x1c, true /* little endian */) & VM_MEMMASK; - if (newBlockPos + newBlockSize >= VM_MEMSIZE) { - newBlockPos = newBlockSize = 0; - } - prg.FilteredData = this.mem_.subarray(newBlockPos, newBlockPos + newBlockSize); - - prg.GlobalData = new Uint8Array(0); - - const dataSize = Math.min(dataView.getUint32(0x30), (VM_GLOBALMEMSIZE - VM_FIXEDGLOBALSIZE)); - if (dataSize != 0) { - const len = dataSize + VM_FIXEDGLOBALSIZE; - prg.GlobalData = new Uint8Array(len); - prg.GlobalData.set(mem.subarray(VM_GLOBALMEMADDR, VM_GLOBALMEMADDR + len)); - } - } - - /** - * @param {Array} preparedCodes - * @return {boolean} - */ - executeCode(preparedCodes) { - let codeIndex = 0; - let cmd = preparedCodes[codeIndex]; - // TODO: Why is this an infinite loop instead of just returning - // when a VM_RET is hit? - while (1) { - switch (cmd.OpCode) { - case VM_Commands.VM_RET: - if (this.R_[7] >= VM_MEMSIZE) { - return true; - } - //SET_IP(GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK])); - this.R_[7] += 4; - continue; - - case VM_Commands.VM_STANDARD: - this.executeStandardFilter(cmd.Op1.Data); - break; - - default: - console.error('RarVM OpCode not supported: ' + getDebugString(VM_Commands, cmd.OpCode)); - break; - } // switch (cmd.OpCode) - codeIndex++; - cmd = preparedCodes[codeIndex]; - } - } - - /** - * @param {number} filterType - */ - executeStandardFilter(filterType) { - switch (filterType) { - case VM_StandardFilters.VMSF_RGB: { - const dataSize = this.R_[4]; - const width = this.R_[0] - 3; - const posR = this.R_[1]; - const Channels = 3; - let srcOffset = 0; - let destOffset = dataSize; - - // byte *SrcData=Mem,*DestData=SrcData+DataSize; - // SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize); - const dataView = new DataView(this.mem_.buffer, VM_GLOBALMEMADDR /* offset */); - dataView.setUint32(0x20 /* byte offset */, - dataSize /* value */, - true /* little endian */); - - if (dataSize >= (VM_GLOBALMEMADDR / 2) || posR < 0) { - break; - } - - for (let curChannel = 0; curChannel < Channels; ++curChannel) { - let prevByte=0; - - for (let i = curChannel; i < dataSize; i += Channels) { - let predicted; - const upperPos = i - width; - if (upperPos >= 3) { - const upperByte = this.mem_[destOffset + upperPos]; - const upperLeftByte = this.mem_[destOffset + upperPos - 3]; - predicted = prevByte + upperByte - upperLeftByte; - - const pa = Math.abs(predicted - prevByte); - const pb = Math.abs(predicted - upperByte); - const pc = Math.abs(predicted - upperLeftByte); - if (pa <= pb && pa <= pc) { - predicted = prevByte; - } else if (pb <= pc) { - predicted = upperByte; - } else { - predicted = upperLeftByte; - } - } else { - predicted = prevByte; - } - //DestData[I]=PrevByte=(byte)(Predicted-*(SrcData++)); - prevByte = (predicted - this.mem_[srcOffset++]) & 0xff; - this.mem_[destOffset + i] = prevByte; - } - } - for (let i = posR, border = dataSize - 2; i < border; i += 3) { - const g = this.mem_[destOffset + i + 1]; - this.mem_[destOffset + i] += g; - this.mem_[destOffset + i + 2] += g; - } - - break; - } - case VM_StandardFilters.VMSF_DELTA: { - const dataSize = this.R_[4]; - const channels = this.R_[0]; - let srcPos = 0; - const border = dataSize * 2; - - //SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize); - const dataView = new DataView(this.mem_.buffer, VM_GLOBALMEMADDR); - dataView.setUint32(0x20 /* byte offset */, - dataSize /* value */, - true /* little endian */); - - if (dataSize >= VM_GLOBALMEMADDR / 2) { - break; - } - - // Bytes from same channels are grouped to continual data blocks, - // so we need to place them back to their interleaving positions. - for (let curChannel = 0; curChannel < channels; ++curChannel) { - let prevByte = 0; - for (let destPos = dataSize + curChannel; destPos < border; destPos += channels) { - prevByte = (prevByte - this.mem_[srcPos++]) & 0xff; - this.mem_[destPos] = prevByte; - } - } - - break; - } - - default: - console.error('RarVM Standard Filter not supported: ' + getDebugString(VM_StandardFilters, filterType)); - break; - } - } - - /** - * @param {Uint8Array} code - * @param {VM_PreparedProgram} prg - */ - prepare(code, prg) { - let codeSize = code.length; - - //InitBitInput(); - //memcpy(InBuf,Code,Min(CodeSize,BitInput::MAX_SIZE)); - const bstream = new bitjs.io.BitStream(code.buffer, true /* rtl */); - - // Calculate the single byte XOR checksum to check validity of VM code. - let xorSum = 0; - for (let i = 1; i < codeSize; ++i) { - xorSum ^= code[i]; - } - - bstream.readBits(8); - - prg.Cmd = []; // TODO: Is this right? I don't see it being done in rarvm.cpp. - - // VM code is valid if equal. - if (xorSum == code[0]) { - const filterType = this.isStandardFilter(code); - if (filterType != VM_StandardFilters.VMSF_NONE) { - // VM code is found among standard filters. - const curCmd = new VM_PreparedCommand(); - prg.Cmd.push(curCmd); - - curCmd.OpCode = VM_Commands.VM_STANDARD; - curCmd.Op1.Data = filterType; - // TODO: Addr=&CurCmd->Op1.Data - curCmd.Op1.Addr = [curCmd.Op1.Data]; - curCmd.Op2.Addr = [null]; // &CurCmd->Op2.Data; - curCmd.Op1.Type = VM_OpType.VM_OPNONE; - curCmd.Op2.Type = VM_OpType.VM_OPNONE; - codeSize = 0; - } - - const dataFlag = bstream.readBits(1); - - // Read static data contained in DB operators. This data cannot be - // changed, it is a part of VM code, not a filter parameter. - - if (dataFlag & 0x8000) { - const dataSize = RarVM.readData(bstream) + 1; - // TODO: This accesses the byte pointer of the bstream directly. Is that ok? - for (let i = 0; i < bstream.bytePtr < codeSize && i < dataSize; ++i) { - // Append a byte to the program's static data. - const newStaticData = new Uint8Array(prg.StaticData.length + 1); - newStaticData.set(prg.StaticData); - newStaticData[newStaticData.length - 1] = bstream.readBits(8); - prg.StaticData = newStaticData; - } - } - - while (bstream.bytePtr < codeSize) { - const curCmd = new VM_PreparedCommand(); - prg.Cmd.push(curCmd); // Prg->Cmd.Add(1) - const flag = bstream.peekBits(1); - if (!flag) { // (Data&0x8000)==0 - curCmd.OpCode = bstream.readBits(4); - } else { - curCmd.OpCode = (bstream.readBits(6) - 24); - } - - if (VM_CmdFlags[curCmd.OpCode] & VMCF_BYTEMODE) { - curCmd.ByteMode = (bstream.readBits(1) != 0); - } else { - curCmd.ByteMode = 0; - } - curCmd.Op1.Type = VM_OpType.VM_OPNONE; - curCmd.Op2.Type = VM_OpType.VM_OPNONE; - const opNum = (VM_CmdFlags[curCmd.OpCode] & VMCF_OPMASK); - curCmd.Op1.Addr = null; - curCmd.Op2.Addr = null; - if (opNum > 0) { - this.decodeArg(curCmd.Op1, curCmd.ByteMode, bstream); // reading the first operand - if (opNum == 2) { - this.decodeArg(curCmd.Op2, curCmd.ByteMode, bstream); // reading the second operand - } else { - if (curCmd.Op1.Type == VM_OpType.VM_OPINT && (VM_CmdFlags[curCmd.OpCode] & (VMCF_JUMP|VMCF_PROC))) { - // Calculating jump distance. - let distance = curCmd.Op1.Data; - if (distance >= 256) { - distance -= 256; - } else { - if (distance >= 136) { - distance -= 264; - } else { - if (distance >= 16) { - distance -= 8; - } else { - if (distance >= 8) { - distance -= 16; - } - } - } - distance += prg.Cmd.length; - } - curCmd.Op1.Data = distance; - } - } - } // if (OpNum>0) - } // while ((uint)InAddrOp1.Data - curCmd.Op1.Addr = [curCmd.Op1.Data]; - curCmd.Op2.Addr = [curCmd.Op2.Data]; - curCmd.Op1.Type = VM_OpType.VM_OPNONE; - curCmd.Op2.Type = VM_OpType.VM_OPNONE; - - // If operand 'Addr' field has not been set by DecodeArg calls above, - // let's set it to point to operand 'Data' field. It is necessary for - // VM_OPINT type operands (usual integers) or maybe if something was - // not set properly for other operands. 'Addr' field is required - // for quicker addressing of operand data. - for (let i = 0; i < prg.Cmd.length; ++i) { - const cmd = prg.Cmd[i]; - if (cmd.Op1.Addr == null) { - cmd.Op1.Addr = [cmd.Op1.Data]; - } - if (cmd.Op2.Addr == null) { - cmd.Op2.Addr = [cmd.Op2.Data]; - } - } - - /* - #ifdef VM_OPTIMIZE - if (CodeSize!=0) - Optimize(Prg); - #endif - */ - } - - /** - * @param {Uint8Array} arr The byte array to set a value in. - * @param {number} value The unsigned 32-bit value to set. - * @param {number} offset Offset into arr to start setting the value, defaults to 0. - */ - setLowEndianValue(arr, value, offset) { - const i = offset || 0; - arr[i] = value & 0xff; - arr[i + 1] = (value >>> 8) & 0xff; - arr[i + 2] = (value >>> 16) & 0xff; - arr[i + 3] = (value >>> 24) & 0xff; - } - - /** - * Sets a number of bytes of the VM memory at the given position from a - * source buffer of bytes. - * @param {number} pos The position in the VM memory to start writing to. - * @param {Uint8Array} buffer The source buffer of bytes. - * @param {number} dataSize The number of bytes to set. - */ - setMemory(pos, buffer, dataSize) { - if (pos < VM_MEMSIZE) { - const numBytes = Math.min(dataSize, VM_MEMSIZE - pos); - for (let i = 0; i < numBytes; ++i) { - this.mem_[pos + i] = buffer[i]; - } - } - } - - /** - * Static function that reads in the next set of bits for the VM - * (might return 4, 8, 16 or 32 bits). - * @param {bitjs.io.BitStream} bstream A RTL bit stream. - * @return {number} The value of the bits read. - */ - static readData(bstream) { - // Read in the first 2 bits. - const flags = bstream.readBits(2); - switch (flags) { // Data&0xc000 - // Return the next 4 bits. - case 0: - return bstream.readBits(4); // (Data>>10)&0xf - - case 1: // 0x4000 - // 0x3c00 => 0011 1100 0000 0000 - if (bstream.peekBits(4) == 0) { // (Data&0x3c00)==0 - // Skip the 4 zero bits. - bstream.readBits(4); - // Read in the next 8 and pad with 1s to 32 bits. - return (0xffffff00 | bstream.readBits(8)) >>> 0; // ((Data>>2)&0xff) - } - - // Else, read in the next 8. - return bstream.readBits(8); - - // Read in the next 16. - case 2: // 0x8000 - const val = bstream.getBits(); - bstream.readBits(16); - return val; //bstream.readBits(16); - - // case 3 - default: - return (bstream.readBits(16) << 16) | bstream.readBits(16); - } - } -} - -// ============================================================================================== // // Progress variables. let currentFilename = ""; let currentFileNumber = 0; @@ -2035,10 +464,12 @@ function Unpack15(bstream, Solid) { function Unpack20(bstream, Solid) { const destUnpSize = rBuffer.data.length; let oldDistPtr = 0; - - RarReadTables20(bstream); + + if (!Solid) { + RarReadTables20(bstream); + } while (destUnpSize > rBuffer.ptr) { - const num = RarDecodeNumber(bstream, LD); + let num = RarDecodeNumber(bstream, LD); if (num < 256) { rBuffer.insertByte(num); continue; @@ -2125,6 +556,7 @@ const rMC20 = 257; const UnpOldTable20 = new Array(rMC20 * 4); +// TODO: This function should return a boolean value, see unpack20.cpp. function RarReadTables20(bstream) { const BitLength = new Array(rBC20); const Table = new Array(rMC20 * 4); @@ -2758,12 +1190,13 @@ function RarInsertOldDist(distance) { */ function RarCopyString(len, distance) { let srcPtr = rBuffer.ptr - distance; + // If we need to go back to previous buffers, then seek back. if (srcPtr < 0) { let l = rOldBuffers.length; while (srcPtr < 0) { srcPtr = rOldBuffers[--l].data.length + srcPtr; } - // TODO: lets hope that it never needs to read beyond file boundaries + // TODO: lets hope that it never needs to read across buffer boundaries while (len--) { rBuffer.insertByte(rOldBuffers[l].data[srcPtr++]); } @@ -2783,7 +1216,7 @@ function RarCopyString(len, distance) { function unpack(v) { // TODO: implement what happens when unpVer is < 15 const Ver = v.header.unpVer <= 15 ? 15 : v.header.unpVer; - const Solid = v.header.LHD_SOLID; + const Solid = v.header.flags.LHD_SOLID; const bstream = new bitjs.io.BitStream(v.fileData.buffer, true /* rtl */, v.fileData.byteOffset, v.fileData.byteLength ); rBuffer = new bitjs.io.ByteBuffer(v.header.unpackedSize); @@ -2804,7 +1237,7 @@ function unpack(v) { Unpack29(bstream, Solid); break; } // switch(method) - + rOldBuffers.push(rBuffer); // TODO: clear these old buffers when there's over 4MB of history return rBuffer.data;