1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/common/safe_browsing/zip_analyzer.h"
6
7#include "base/logging.h"
8#include "chrome/common/safe_browsing/download_protection_util.h"
9#include "third_party/zlib/google/zip_reader.h"
10
11namespace safe_browsing {
12namespace zip_analyzer {
13
14void AnalyzeZipFile(base::File zip_file, Results* results) {
15  zip::ZipReader reader;
16  // OpenFromPlatformFile may close the handle even when it fails, but there is
17  // no way to know if it did that or not. Assume it did (that's the common
18  // case).
19  if (!reader.OpenFromPlatformFile(zip_file.TakePlatformFile())) {
20    VLOG(1) << "Failed to open zip file";
21    return;
22  }
23
24  bool advanced = true;
25  for (; reader.HasMore(); advanced = reader.AdvanceToNextEntry()) {
26    if (!advanced) {
27      VLOG(1) << "Could not advance to next entry, aborting zip scan.";
28      return;
29    }
30    if (!reader.OpenCurrentEntryInZip()) {
31      VLOG(1) << "Failed to open current entry in zip file";
32      continue;
33    }
34    const base::FilePath& file = reader.current_entry_info()->file_path();
35    if (download_protection_util::IsBinaryFile(file)) {
36      // Don't consider an archived archive to be executable, but record
37      // a histogram.
38      if (download_protection_util::IsArchiveFile(file)) {
39        results->has_archive = true;
40      } else {
41        VLOG(2) << "Downloaded a zipped executable: " << file.value();
42        results->has_executable = true;
43        break;
44      }
45    } else {
46      VLOG(3) << "Ignoring non-binary file: " << file.value();
47    }
48  }
49  results->success = true;
50}
51
52}  // namespace zip_analyzer
53}  // namespace safe_browsing
54