<commit_before>// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "bin/loader.h"

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/dfe.h"
#include "bin/error_exit.h"
#include "bin/extensions.h"
#include "bin/file.h"
#include "bin/gzip.h"
#include "bin/lockers.h"
#include "bin/utils.h"
#include "include/dart_tools_api.h"
#include "platform/growable_array.h"

namespace dart {
namespace bin {

#if !defined(DART_PRECOMPILED_RUNTIME)
extern DFE dfe;
#endif

Dart_Handle Loader::InitForSnapshot(const char* snapshot_uri,
                                    IsolateData* isolate_data) {
  ASSERT(isolate_data != NULL);

  return Loader::Init(isolate_data->packages_file(),
                      DartUtils::original_working_directory, snapshot_uri);
}

// Initialize package resolution state.
Dart_Handle Loader::Init(const char* packages_file,
                         const char* working_directory,
                         const char* root_script_uri) {
  const int kNumArgs = 3;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = (packages_file == NULL)
                     ? Dart_Null()
                     : Dart_NewStringFromCString(packages_file);
  dart_args[1] = Dart_NewStringFromCString(working_directory);
  dart_args[2] = (root_script_uri == NULL)
                     ? Dart_Null()
                     : Dart_NewStringFromCString(root_script_uri);
  return Dart_Invoke(DartUtils::LookupBuiltinLib(),
                     DartUtils::NewString("_Init"), kNumArgs, dart_args);
}

static bool PathContainsSeparator(const char* path) {
  return (strchr(path, '/') != NULL) ||
         ((strncmp(File::PathSeparator(), "/", 1) != 0) &&
          (strstr(path, File::PathSeparator()) != NULL));
}

#define RETURN_ERROR(result)                                                   \
  if (Dart_IsError(result)) return result;

Dart_Handle Loader::LoadImportExtension(const char* url_string,
                                        Dart_Handle library) {
  const char* lib_uri_str = NULL;
  Dart_Handle lib_uri = Dart_LibraryResolvedUrl(library);
  ASSERT(!Dart_IsError(lib_uri));
  Dart_Handle result = Dart_StringToCString(lib_uri, &lib_uri_str);
  RETURN_ERROR(result);

  UriDecoder decoder(lib_uri_str);
  lib_uri_str = decoder.decoded();

  if (strncmp(lib_uri_str, "http://", 7) == 0 ||
      strncmp(lib_uri_str, "https://", 8) == 0 ||
      strncmp(lib_uri_str, "data://", 7) == 0) {
    return DartUtils::NewError(
        "Cannot load native extensions over http: or https: or data: %s",
        lib_uri_str);
  }

  char* lib_path = NULL;
  if (strncmp(lib_uri_str, "file://", 7) == 0) {
    lib_path = DartUtils::DirName(lib_uri_str + 7);
  } else {
    lib_path = strdup(lib_uri_str);
  }

  const char* path = DartUtils::RemoveScheme(url_string);
  if (!File::IsAbsolutePath(path) && PathContainsSeparator(path)) {
    return DartUtils::NewError(
        "Native extension path must be absolute, or simply the file name: %s",
        path);
  }

  result = Extensions::LoadExtension(lib_path, path, library);
  free(lib_path);
  return result;
}

Dart_Handle Loader::ReloadNativeExtensions() {
  Dart_Handle scheme =
      Dart_NewStringFromCString(DartUtils::kDartExtensionScheme);
  Dart_Handle extension_imports = Dart_GetImportsOfScheme(scheme);
  RETURN_ERROR(extension_imports);<commit_msg>[standalone] Fix memory leak when failing to load a native extension.<commit_after>// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "bin/loader.h"

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/dfe.h"
#include "bin/error_exit.h"
#include "bin/extensions.h"
#include "bin/file.h"
#include "bin/gzip.h"
#include "bin/lockers.h"
#include "bin/utils.h"
#include "include/dart_tools_api.h"
#include "platform/growable_array.h"

namespace dart {
namespace bin {

#if !defined(DART_PRECOMPILED_RUNTIME)
extern DFE dfe;
#endif

Dart_Handle Loader::InitForSnapshot(const char* snapshot_uri,
                                    IsolateData* isolate_data) {
  ASSERT(isolate_data != NULL);

  return Loader::Init(isolate_data->packages_file(),
                      DartUtils::original_working_directory, snapshot_uri);
}

// Initialize package resolution state.
Dart_Handle Loader::Init(const char* packages_file,
                         const char* working_directory,
                         const char* root_script_uri) {
  const int kNumArgs = 3;
  Dart_Handle dart_args[kNumArgs];
  dart_args[0] = (packages_file == NULL)
                     ? Dart_Null()
                     : Dart_NewStringFromCString(packages_file);
  dart_args[1] = Dart_NewStringFromCString(working_directory);
  dart_args[2] = (root_script_uri == NULL)
                     ? Dart_Null()
                     : Dart_NewStringFromCString(root_script_uri);
  return Dart_Invoke(DartUtils::LookupBuiltinLib(),
                     DartUtils::NewString("_Init"), kNumArgs, dart_args);
}

static bool PathContainsSeparator(const char* path) {
  return (strchr(path, '/') != NULL) ||
         ((strncmp(File::PathSeparator(), "/", 1) != 0) &&
          (strstr(path, File::PathSeparator()) != NULL));
}

#define RETURN_ERROR(result)                                                   \
  if (Dart_IsError(result)) return result;

Dart_Handle Loader::LoadImportExtension(const char* url_string,
                                        Dart_Handle library) {
  const char* lib_uri_str = NULL;
  Dart_Handle lib_uri = Dart_LibraryResolvedUrl(library);
  ASSERT(!Dart_IsError(lib_uri));
  Dart_Handle result = Dart_StringToCString(lib_uri, &lib_uri_str);
  RETURN_ERROR(result);

  UriDecoder decoder(lib_uri_str);
  lib_uri_str = decoder.decoded();

  if (strncmp(lib_uri_str, "http://", 7) == 0 ||
      strncmp(lib_uri_str, "https://", 8) == 0 ||
      strncmp(lib_uri_str, "data://", 7) == 0) {
    return DartUtils::NewError(
        "Cannot load native extensions over http: or https: or data: %s",
        lib_uri_str);
  }

  char* lib_path = NULL;
  if (strncmp(lib_uri_str, "file://", 7) == 0) {
    lib_path = DartUtils::DirName(lib_uri_str + 7);
  } else {
    lib_path = strdup(lib_uri_str);
  }

  const char* path = DartUtils::RemoveScheme(url_string);
  if (!File::IsAbsolutePath(path) && PathContainsSeparator(path)) {
    free(lib_path);
    return DartUtils::NewError(
        "Native extension path must be absolute, or simply the file name: %s",
        path);
  }

  result = Extensions::LoadExtension(lib_path, path, library);
  free(lib_path);
  return result;
}

Dart_Handle Loader::ReloadNativeExtensions() {
  Dart_Handle scheme =
      Dart_NewStringFromCString(DartUtils::kDartExtensionScheme);
  Dart_Handle extension_imports = Dart_GetImportsOfScheme(scheme);
  RETURN_ERROR(extension_imports);
{'fraction_non_alphanumeric': 0.11963882618510158, 'fraction_numerical': 0.00536117381489842, 'mean_word_length': 3.2730560578661843, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '772062', 'n_tokens_mistral': 2358, 'n_tokens_neox': 2256, 'n_words': 496}