0

I need to download a tar.gz file, and replace a directory in it with the contents of another tar.gz file. So far, I've tried the following gems, and found them lacking

  • archive-tar2: it lost the penultimate path separator ("/") so couldn't actually extract
  • archive-tarsimple: simply didn't extract the compressed tarball, and returned no error msg
  • minitar: ran into a bug where it failed for filepaths longer than 100 characters
  • archive-tar-minitar - fails the same as its parent Errno::ENAMETOOLONG / File name too long
  • libarchive: bundle install failed the gcc compile (even after successful brew install libarchive)

I'm starting to lose faith. Is there a good, up to date, well maintained tar archive gem that just works? I'd prefer one that doesn't call out to the command line, since I'd like to eliminate the possibility of commandline injection attacks. But at this point I'll take anything that avoids manually calling out to a shell.

nont
  • 9,322
  • 7
  • 62
  • 82
  • Have you tried copying from a couple of Gems::Package::TarReader as in http://stackoverflow.com/a/11505644/931925 to a Gems::Package::TarWriter? (Sorry I am not well versed in Ruby so could easily misunderstand something.) – minopret Mar 09 '14 at 15:00
  • no but I'll give it a shot – nont Mar 09 '14 at 16:41

2 Answers2

0

You can also check out archive-tar-minitar, it is partially based on minitar that you already tested out, and it doesn't seem that it emmits calls to the command line.

sidney
  • 2,704
  • 3
  • 28
  • 44
  • thanks for the suggestion. it fails the same way minitar did. I'm adding it to my tar gem wall of shame. – nont Mar 07 '14 at 21:15
  • man, if I were you, I would simply use a system command depending on the OS you use. It would still be safe against injection. What are your needs? – sidney Mar 07 '14 at 21:18
  • ya, that's what I was doing before, but actually, the final filename will depend on user input, so its really not safe from injection. When I finally run out of patience for this mess, I'll go back to doing that and add character whitelisting, which is better than nothing. – nont Mar 07 '14 at 21:21
  • Instead of whitelisting a set of words, if you need a good security, I strongly advise you to parse the user's entry to convert it to letters from A-Z, there's no way that any injection could occur in the first place. However the user shouldn't be able to insert everything but that would be a fine counter-measure. [Edit]: Oh sry, you already meant that by `character whitelisting` ;) – sidney Mar 07 '14 at 21:25
  • Yup, that's what I meant, but yes, whitelisting is better than blacklisting. I'm sort of shocked at the poor state of ruby archiving gems. – nont Mar 07 '14 at 21:29
  • I think that most of the time, devs also use their own implementation. It may be that those guys who made those gems made them for their own use as well, and as they don't need them, they just... drop them unfortunately. – sidney Mar 07 '14 at 21:32
0

I ended up giving up with using a gem to manipulate the tar archives, and just doing it by shelling out to the commandline.

`cd #{container} && tar xvfz sdk.tar.gz`    
`cd #{container} && tar xvfz Wizard.tar.gz`

    #update the framework packaged with the wizard
    FileUtils.rm_rf(container + "/Wizard.app/Contents/Resources/SDK.bundle")
    FileUtils.rm_rf(container + "/Wizard.app/Contents/Resources/SDK.framework")
    FileUtils.mv(container +  "/resources/SDK.bundle", container + "/Wizard.app/Contents/Resources/")
    FileUtils.mv(container +  "/resources/SDK.framework", container + "/Wizard.app/Contents/Resources/")

    config_plist =  render_to_string({
             file: 'site/_wizard_config',
             layout: false,
             locals: { app_id: @version.app.id },
             formats: 'xml'
            })  

File.open(container + "/Wizard.app/Contents/Resources/Configuration.plist", 'w') { |file| file.write( config_plist ) } 

`cd #{container} && rm Wizard.tar.gz`    
`cd #{container} && tar -cvf Wizard.tar 'Wizard.app'`
`cd #{container} && gzip Wizard.tar`

All these backticks make me feel like I'm writing Perl again.

nont
  • 9,322
  • 7
  • 62
  • 82