<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: rar.now</title>
    <description>The latest articles on DEV Community by rar.now (@rarnow).</description>
    <link>https://dev.to/rarnow</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4236966%2F2d9e8358-7c6f-483c-b2c7-b934c26e26fd.png</url>
      <title>DEV Community: rar.now</title>
      <link>https://dev.to/rarnow</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rarnow"/>
    <language>en</language>
    <item>
      <title>Working with RAR archives in 2026: extracting, converting and validating them in code</title>
      <dc:creator>rar.now</dc:creator>
      <pubDate>Tue, 10 Nov 2026 12:11:42 +0000</pubDate>
      <link>https://dev.to/rarnow/working-with-rar-archives-in-2026-extracting-converting-and-validating-them-in-code-2fdn</link>
      <guid>https://dev.to/rarnow/working-with-rar-archives-in-2026-extracting-converting-and-validating-them-in-code-2fdn</guid>
      <description>&lt;p&gt;A vendor drops a &lt;code&gt;.rar&lt;/code&gt; into a support inbox, your CI expects a ZIP or a tarball, and the first library you try either cannot open it, cannot take the password, or writes files somewhere you did not ask for. The extension looks simple. The format is not.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://rar.now" rel="noopener noreferrer"&gt;rar.now&lt;/a&gt; because I kept hitting that mismatch in hand-offs and build pipelines, and I am the site's maker, so I will be explicit about that. Here is how to handle RAR archives in 2026 without surprises.&lt;/p&gt;

&lt;h2&gt;
  
  
  RAR4 and RAR5 are not the same format
&lt;/h2&gt;

&lt;p&gt;Both use the &lt;code&gt;.rar&lt;/code&gt; extension, and they are incompatible on disk. WinRAR has defaulted to RAR5 since 2013 and writes RAR4 only if you ask it to; older RAR4-only tools will reject a current archive. Tell them apart by the signature, not the filename:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;RAR4&lt;/th&gt;
&lt;th&gt;RAR5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Signature&lt;/td&gt;
&lt;td&gt;&lt;code&gt;52 61 72 21 1A 07 00&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;52 61 72 21 1A 07 01 00&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Names&lt;/td&gt;
&lt;td&gt;OEM / Unicode&lt;/td&gt;
&lt;td&gt;UTF-8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File checksum&lt;/td&gt;
&lt;td&gt;CRC-32&lt;/td&gt;
&lt;td&gt;CRC-32 or BLAKE2sp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;AES-128&lt;/td&gt;
&lt;td&gt;AES-256 (PBKDF2-HMAC-SHA256)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dictionary&lt;/td&gt;
&lt;td&gt;up to 4 MB&lt;/td&gt;
&lt;td&gt;up to 1 GB; up to 64 GB in RAR 7.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;rarVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;rar4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x61&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;rar5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x52&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x61&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x1a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subarray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rar5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subarray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rar4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not trust &lt;code&gt;file.type&lt;/code&gt;. Browsers often send &lt;code&gt;application/octet-stream&lt;/code&gt;, or flip between &lt;code&gt;application/x-rar-compressed&lt;/code&gt; and &lt;code&gt;application/vnd.rar&lt;/code&gt;. Read the first eight bytes on the server.&lt;/p&gt;

&lt;p&gt;Encrypted headers hide the file list until you have the password. Solid archives compress files as one stream, so extracting one entry can mean decompressing everything before it, and some libraries fail on solid RAR4. A RAR 7.0 dictionary larger than 4 GB needs UnRAR 7.0 or newer. Windows 11 File Explorer can extract unencrypted RAR files from 23H2 onward, but encrypted archives, repair, and creation still need a dedicated tool. macOS and most CI images have no built-in RAR extractor.&lt;/p&gt;

&lt;h2&gt;
  
  
  You can extract RAR. You generally cannot create it
&lt;/h2&gt;

&lt;p&gt;RAR is proprietary. Only WinRAR and RARLAB's commercial &lt;code&gt;rar&lt;/code&gt; CLI write a compatible archive. RARLAB publishes UnRAR source, which you may use to extract — including in commercial products — but the license forbids using that code to build a RAR-compatible archiver. It is not an OSI open-source license.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UnRAR&lt;/strong&gt; (the official library or &lt;code&gt;unrar&lt;/code&gt; CLI) opens RAR4 and RAR5, including encrypted archives, volumes, and large dictionaries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;libarchive&lt;/strong&gt; (and therefore &lt;code&gt;bsdtar&lt;/code&gt;, plus Windows 11's built-in extractor) reads RAR4 and RAR5 under a BSD license. It does not decrypt password-protected RAR, and it does not extract solid RAR4. Solid RAR5 works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;7-Zip&lt;/strong&gt; extracts RAR4 and RAR5 (RAR5 since version 15.06). Its RAR decompressor is based on UnRAR source and carries the same "no archiver" restriction. On Debian and Ubuntu, RAR support often lives in a separate &lt;code&gt;7zip-rar&lt;/code&gt; package for that reason.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your pipeline needs an archive you can create and read everywhere, convert to ZIP, 7Z or TAR after extraction. Do not plan to emit &lt;code&gt;.rar&lt;/code&gt; from application code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node and Python: pick a backend on purpose
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Python.&lt;/strong&gt; &lt;a href="https://rarfile.readthedocs.io/" rel="noopener noreferrer"&gt;&lt;code&gt;rarfile&lt;/code&gt;&lt;/a&gt; is the usual choice. It parses the archive in Python and shells out to an external tool for compressed entries: &lt;code&gt;unrar&lt;/code&gt; (best), &lt;code&gt;7z&lt;/code&gt;, &lt;code&gt;unar&lt;/code&gt;, or &lt;code&gt;bsdtar&lt;/code&gt;. The backend on &lt;code&gt;PATH&lt;/code&gt; decides what actually works. &lt;code&gt;bsdtar&lt;/code&gt; inherits libarchive's limits: no passwords, no solid archives, and no multi-volume support. Install &lt;code&gt;unrar&lt;/code&gt; in CI if you need the full format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;rarfile&lt;/span&gt;

&lt;span class="n"&gt;rf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rarfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RarFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"bundle.rar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# rf.needs_password() — call rf.setpassword(...) before extract&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;infolist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Node.js.&lt;/strong&gt; There is no blessed standard-library extractor. &lt;a href="https://www.npmjs.com/package/node-unrar-js" rel="noopener noreferrer"&gt;&lt;code&gt;node-unrar-js&lt;/code&gt;&lt;/a&gt; embeds official UnRAR compiled to WebAssembly, so it handles RAR4 and RAR5, Unicode names, and passwords without a native toolchain. It does not support multi-volume archives. Keep the UnRAR license in mind: the npm wrapper is MIT, the decoder it ships is still UnRAR. Calling &lt;code&gt;7z&lt;/code&gt; or &lt;code&gt;unrar&lt;/code&gt; from a worker is often clearer in production than bundling WASM.&lt;/p&gt;

&lt;p&gt;List first, extract second. Look at filenames, unpacked sizes, encryption flags and volume markers before you write anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multipart volumes and recovery records
&lt;/h2&gt;

&lt;p&gt;A large archive may be split into volumes. Current sets are usually named &lt;code&gt;name.part1.rar&lt;/code&gt;, &lt;code&gt;name.part2.rar&lt;/code&gt;; older RAR4 sets use &lt;code&gt;name.rar&lt;/code&gt;, &lt;code&gt;name.r00&lt;/code&gt;, &lt;code&gt;name.r01&lt;/code&gt;. Open the first volume; tools locate the rest by name, in the same directory. Copy every volume, including any &lt;code&gt;.rev&lt;/code&gt; recovery volumes, before you extract.&lt;/p&gt;

&lt;p&gt;RAR can also store a recovery record inside the archive, and optionally separate &lt;code&gt;.rev&lt;/code&gt; files, so a tool can rebuild a limited amount of damage — RAR5 uses Reed-Solomon data for this. Test before you extract: &lt;code&gt;unrar t bundle.rar&lt;/code&gt; checks headers and payload checksums (CRC-32, or BLAKE2sp on some RAR5 archives). Repair is a different operation. The free &lt;code&gt;unrar&lt;/code&gt; binary tests and extracts; rebuilding a damaged archive is a job for WinRAR, the commercial &lt;code&gt;rar r&lt;/code&gt; command, or a repair tool, and it only has a chance when recovery data is present.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extract untrusted archives as if they are hostile
&lt;/h2&gt;

&lt;p&gt;Zip Slip is not a ZIP-only bug. Snyk documented the same path-traversal pattern in RAR, 7z and TAR extractors: an entry named &lt;code&gt;../../etc/cron.d/x&lt;/code&gt; will leave the destination directory if you naively join and write. Archive bombs are the other failure mode: a small file that expands to gigabytes, or thousands of entries. Nested archives only become a problem if your code opens them again.&lt;/p&gt;

&lt;p&gt;Treat every untrusted RAR like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extract into a fresh directory you created, not an existing tree that may already contain symlinks or junctions.&lt;/li&gt;
&lt;li&gt;Resolve each destination path and reject it unless it stays inside that directory. Checking the raw name for &lt;code&gt;..&lt;/code&gt; is not enough: absolute paths and already-present symlinks will bypass a string filter.&lt;/li&gt;
&lt;li&gt;Cap entry count, per-file unpacked size, total unpacked bytes, and path depth. Trust a running byte count, not only the header — a lying header is part of the attack.&lt;/li&gt;
&lt;li&gt;Refuse symlink and hardlink entries unless you have a reason to honor them, do not extract as root, and do not overwrite files outside the job.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;"node:path"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;safeJoin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entryName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entryName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sep&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`refusing path traversal: ${entryName}`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A conversion pipeline should do the same work: extract safely to a staging directory, then pack a new ZIP, 7Z or TAR from the files you actually wrote. Recovery records, archive comments, some attributes, and solid compression will not survive the repack, so keep the original if those matter.&lt;/p&gt;

&lt;p&gt;If you only need to convert or inspect a handful of archives and you are not building a pipeline, a browser tool is enough. &lt;a href="https://rar.now" rel="noopener noreferrer"&gt;rar.now&lt;/a&gt; is the one I use for that job: RAR to ZIP, 7Z or TAR, plus extraction, an integrity test, repair when the archive has recovery data, and tools for multipart and password-protected sets. It does not create RAR files. Guests can use it with no account — 10 conversions a day, 10 MB per file. Uploads travel over HTTPS, work runs on the server, and guest files are deleted within 24 hours.&lt;/p&gt;

&lt;p&gt;For a product, make the format and the safety checks part of the upload path, so the first artifact your build sees is already a ZIP or tarball you packed yourself.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>python</category>
      <category>security</category>
    </item>
  </channel>
</rss>
