summaryrefslogtreecommitdiff
path: root/lib/qt-tar-xz/QTarDecode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/qt-tar-xz/QTarDecode.cpp')
-rw-r--r--lib/qt-tar-xz/QTarDecode.cpp233
1 files changed, 147 insertions, 86 deletions
diff --git a/lib/qt-tar-xz/QTarDecode.cpp b/lib/qt-tar-xz/QTarDecode.cpp
index fe15359..e1d9bce 100644
--- a/lib/qt-tar-xz/QTarDecode.cpp
+++ b/lib/qt-tar-xz/QTarDecode.cpp
@@ -1,113 +1,174 @@
/** \file QTarDecode.cpp
\brief To read a tar data block
\author alpha_one_x86
-\version 0.3
-\date 2010
\licence GPL3, see the file COPYING */
#include "QTarDecode.h"
-#include <QDebug>
+
+#include <inttypes.h>
+#include <regex>
+#include <cstring>
+#include <iostream>
+
+static const std::regex isaunsignednumber("^[0-9]+$",std::regex::optimize);
+static const std::regex isaunoctalnumber("^[0-7]+$",std::regex::optimize);
+static const char* const lut = "0123456789ABCDEF";
QTarDecode::QTarDecode()
{
- error="Unknow error";
+ error="Unknown error";
+}
+
+uint64_t QTarDecode::octaltouint64(const std::string &string,bool *ok)
+{
+ if(std::regex_match(string,isaunsignednumber))
+ {
+ if(ok!=NULL)
+ *ok=true;
+ return std::stoi(string,0,8);
+ }
+ else
+ {
+ if(ok!=NULL)
+ *ok=false;
+ return 0;
+ }
+}
+
+uint64_t QTarDecode::stringtouint64(const std::string &string,bool *ok)
+{
+ if(std::regex_match(string,isaunsignednumber))
+ {
+ if(ok!=NULL)
+ *ok=true;
+ return std::stoull(string);
+ }
+ else
+ {
+ if(ok!=NULL)
+ *ok=false;
+ return 0;
+ }
+}
+
+std::string QTarDecode::errorString()
+{
+ return error;
}
-QString QTarDecode::errorString()
+void QTarDecode::setErrorString(const std::string &error)
{
- return error;
+ this->error=error;
+ fileList.clear();
+ dataList.clear();
}
-void QTarDecode::setErrorString(QString error)
+bool QTarDecode::stringStartWith(std::string const &fullString, std::string const &starting)
{
- this->error=error;
- fileList.clear();
- dataList.clear();
+ if (fullString.length() >= starting.length()) {
+ return (fullString.substr(0,starting.length())==starting);
+ } else {
+ return false;
+ }
}
-bool QTarDecode::decodeData(QByteArray data)
+bool QTarDecode::decodeData(const std::vector<char> &data)
{
- setErrorString("Unknow error");
- if(data.size()<1024)
- return false;
- int offset=0;
- while(offset<data.size())
- {
- //load the file name from ascii, from 0+offset with size of 100
- QString fileName=data.mid(0+offset,100);
- //load the file type
- QString fileType=data.mid(156+offset,1);
- //load the ustar string
- QString ustar=data.mid(257+offset,5);
- //load the ustar version
- QString ustarVersion=data.mid(263+offset,2);
- bool ok;
- //load the file size from ascii, from 124+offset with size of 12
- int finalSize=QString(data.mid(124+offset,12)).toUInt(&ok,8);
- //if the size conversion to qulonglong have failed, then qui with error
- if(ok==false)
- {
- //if((offset+1024)==data.size())
- //it's the end of the archive, no more verification
- break;
- /*else
- {
- setErrorString("Unable to convert ascii size at "+QString::number(124+offset)+" to usigned long long: \""+QString(data.mid(124+offset,12))+"\"");
- return false;
- }*/
- }
- //if check if the ustar not found
- if(ustar!="ustar")
- {
- setErrorString("\"ustar\" string not found at "+QString::number(257+offset)+", content: \""+ustar+"\"");
- return false;
- }
- if(ustarVersion!="00")
- {
- setErrorString("ustar version string is wrong, content:\""+ustarVersion+"\"");
- return false;
- }
- //check if the file have the good size for load the data
- if((offset+512+finalSize)>data.size())
- {
- setErrorString("The tar file seem be too short");
- return false;
- }
- if(fileType=="0") //this code manage only the file, then only the file is returned
- {
- QByteArray fileData=data.mid(512+offset,finalSize);
- fileList << fileName;
- dataList << fileData;
- }
- //calculate the offset for the next header
- bool retenu=((finalSize%512)!=0);
- //go to the next header
- offset+=512+(finalSize/512+retenu)*512;
- }
- if(fileList.size()>0)
- {
- QString baseDirToTest=fileList.at(0);
- baseDirToTest.remove(QRegExp("/.*$"));
- baseDirToTest+='/';
- bool isFoundForAllEntries=true;
- for (int i = 0; i < fileList.size(); ++i)
- if(!fileList.at(i).startsWith(baseDirToTest))
- isFoundForAllEntries=false;
- if(isFoundForAllEntries)
- for (int i = 0; i < fileList.size(); ++i)
- fileList[i].remove(0,baseDirToTest.size());
- }
- return true;
+ setErrorString("Unknown error");
+ if(data.size()<1024)
+ return false;
+ unsigned int offset=0;
+ while(offset<data.size())
+ {
+ //load the file name from ascii, from 0+offset with size of 100
+ std::string fileName(data.data()+offset,100);
+ while(!fileName.empty() && fileName.at(fileName.size()-1)==0x00)
+ fileName.resize(fileName.size()-1);
+ //load the file type
+ std::string fileType(data.data()+156+offset,1);
+ while(!fileName.empty() && fileType.at(fileType.size()-1)==0x00)
+ fileType.resize(fileType.size()-1);
+ //load the ustar string
+ std::string ustar(data.data()+257+offset,5);
+ while(!fileName.empty() && ustar.at(ustar.size()-1)==0x00)
+ ustar.resize(ustar.size()-1);
+ //load the ustar version
+ std::string ustarVersion(data.data()+263+offset,2);
+ while(!fileName.empty() && ustarVersion.at(ustarVersion.size()-1)==0x00)
+ ustarVersion.resize(ustarVersion.size()-1);
+ bool ok=false;
+ //load the file size from ascii, from 124+offset with size of 12
+ uint64_t finalSize=0;
+ std::string sizeString(data.data()+124+offset,12);
+ if(sizeString.at(sizeString.size()-1)==0x00)
+ {
+ //the size is in octal base
+ sizeString.resize(sizeString.size()-1);
+ finalSize=octaltouint64(sizeString,&ok);
+ }
+ else
+ finalSize=stringtouint64(sizeString,&ok);
+ //if the size conversion to qulonglong have failed, then qui with error
+ if(ok==false)
+ {
+ //it's the end of the archive, no more verification
+ break;
+ }
+ //if check if the ustar not found
+ if(ustar!="ustar")
+ {
+ setErrorString("\"ustar\" string not found at "+std::to_string(257+offset)+", content: \""+ustar+"\"");
+ return false;
+ }
+ if(ustarVersion!="00")
+ {
+ setErrorString("ustar version string is wrong, content:\""+ustarVersion+"\"");
+ return false;
+ }
+ //check if the file have the good size for load the data
+ if((offset+512+finalSize)>data.size())
+ {
+ setErrorString("The tar file seem be too short");
+ return false;
+ }
+ if(fileType=="0") //this code manage only the file, then only the file is returned
+ {
+ std::vector<char> newdata;
+ newdata.resize(finalSize);
+ memcpy(newdata.data(),data.data()+512+offset,finalSize);
+ fileList.push_back(fileName);
+ dataList.push_back(newdata);
+ }
+ //calculate the offset for the next header
+ bool retenu=((finalSize%512)!=0);
+ //go to the next header
+ offset+=512+(finalSize/512+retenu)*512;
+ }
+ if(fileList.size()>0)
+ {
+ std::string baseDirToTest=fileList.at(0);
+ std::size_t found = baseDirToTest.find_last_of("/");
+ if(found!=std::string::npos && found>=baseDirToTest.size())
+ baseDirToTest.resize(baseDirToTest.size()-(baseDirToTest.size()-found));
+ bool isFoundForAllEntries=true;
+ for (unsigned int i = 0; i < fileList.size(); ++i)
+ if(!stringStartWith(fileList.at(i),baseDirToTest))
+ isFoundForAllEntries=false;
+ if(isFoundForAllEntries)
+ for (unsigned int i = 0; i < fileList.size(); ++i)
+ fileList[i].erase(0,baseDirToTest.size());
+ }
+ return true;
}
-QStringList QTarDecode::getFileList()
+std::vector<std::string> QTarDecode::getFileList()
{
- return fileList;
+ return fileList;
}
-QList<QByteArray> QTarDecode::getDataList()
+std::vector<std::vector<char> > QTarDecode::getDataList()
{
- return dataList;
+ return dataList;
}