| 117 | return QFile::decodeName(QByteArray(name, qstrnlen(name, 100))); |
| 118 | } |
| 119 | bool Tar::extract(QIODevice* in, QString dst) |
| 120 | { |
| 121 | char buffer[BLOCKSIZE]; |
| 122 | QString name, symlink, firstFolderName; |
| 123 | bool doNotReset = false, ok; |
| 124 | while (true) { |
| 125 | auto n = in->read(buffer, BLOCKSIZE); |
| 126 | if (n != BLOCKSIZE) { // allways expect complete blocks |
| 127 | qCritical() << "The expected blocksize was not respected"; |
| 128 | return false; |
| 129 | } |
| 130 | if (buffer[0] == 0) { // end of archive |
| 131 | return true; |
| 132 | } |
| 133 | int mode = getOctal(buffer + 100, 8, &ok) | QFile::ReadUser | QFile::WriteUser; // hack to ensure write and read permisions |
| 134 | if (!ok) { |
| 135 | qCritical() << "The file mode can't be read"; |
| 136 | return false; |
| 137 | } |
| 138 | // there are names that are exactly 100 bytes long |
| 139 | // and neither longlink nor \0 terminated (bug:101472) |
| 140 | |
| 141 | if (name.isEmpty()) { |
| 142 | name = decodeName(buffer); |
| 143 | if (!firstFolderName.isEmpty() && name.startsWith(firstFolderName)) { |
| 144 | name = name.mid(firstFolderName.size()); |
| 145 | } |
| 146 | } |
| 147 | if (symlink.isEmpty()) |
| 148 | symlink = decodeName(buffer); |
| 149 | qint64 size = getOctal(buffer + 124, 12, &ok); |
| 150 | if (!ok) { |
| 151 | qCritical() << "The file size can't be read"; |
| 152 | return false; |
| 153 | } |
| 154 | switch (TypeFlag(buffer[156])) { |
| 155 | case TypeFlag::Regular: |
| 156 | /* fallthrough */ |
| 157 | case TypeFlag::ARegular: { |
| 158 | auto fileName = FS::PathCombine(dst, name); |
| 159 | if (!FS::ensureFilePathExists(fileName)) { |
| 160 | qCritical() << "Can't ensure the file path to exist: " << fileName; |
| 161 | return false; |
| 162 | } |
| 163 | QFile out(fileName); |
| 164 | if (!out.open(QFile::WriteOnly)) { |
| 165 | qCritical() << "Can't open file:" << fileName; |
| 166 | return false; |
| 167 | } |
| 168 | out.setPermissions(QFile::Permissions(mode)); |
| 169 | while (size > 0) { |
| 170 | QByteArray tmp(BLOCKSIZE, 0); |
| 171 | n = in->read(tmp.data(), BLOCKSIZE); |
| 172 | if (n != BLOCKSIZE) { |
| 173 | qCritical() << "The expected blocksize was not respected when reading file"; |
| 174 | return false; |
| 175 | } |
| 176 | tmp.truncate(qMin(qint64(BLOCKSIZE), size)); |
nothing calls this directly
no test coverage detected