Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  CompleteFile.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "util/CompleteFile.h"

#include <cstring>     // std::strcmp
#include <stdio.h>     // FILE, fileno, fopen, getc, getc_unlocked, _getc_nolock
#include <sys/stat.h>  // stat, fstat

#ifdef __wasi__
#  include "js/Vector.h"
#endif  // __wasi__

#include "js/CharacterEncoding.h"     // EncodeUtf8ToWide, EncodeUtf8ToNarrow
#include "js/ErrorReport.h"           // JS_ReportErrorNumberUTF8
#include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_CANT_OPEN

bool js::ReadCompleteFile(JSContext* cx, FILE* fp, FileContents& buffer) {
  /* Get the complete length of the file, if possible. */
  struct stat st;
  int ok = fstat(fileno(fp), &st);
  if (ok != 0) {
    // Use the Latin1 variant here (and below), because the encoding of
    // strerror() is platform-dependent.
    JS_ReportErrorLatin1(cx, "error reading file: %s", strerror(errno));
    errno = 0;
    return false;
  }
  if ((st.st_mode & S_IFDIR) != 0) {
    JS_ReportErrorLatin1(cx, "error reading file: %s", strerror(EISDIR));
    return false;
  }

  if (st.st_size > 0) {
    if (!buffer.reserve(st.st_size)) {
      return false;
    }
  }

  /* Use the fastest available getc. */
  auto fast_getc =
#if defined(HAVE_GETC_UNLOCKED)
      getc_unlocked
#elif defined(HAVE__GETC_NOLOCK)
      _getc_nolock
#else
      getc
#endif
      ;

  // Read in the whole file. Note that we can't assume the data's length
  // is actually st.st_size, because 1) some files lie about their size
  // (/dev/zero and /dev/random), and 2) reading files in text mode on
  // Windows collapses "\r\n" pairs to single \n characters.
  for (;;) {
    int c = fast_getc(fp);
    if (c == EOF) {
      break;
    }
    if (!buffer.append(c)) {
      return false;
    }
  }

  if (ferror(fp)) {
    // getc failed
    JS_ReportErrorLatin1(cx, "error reading file: %s", strerror(errno));
    errno = 0;
    return false;
  }

  return true;
}

#ifdef __wasi__
static bool NormalizeWASIPath(const char* filename,
                              js::Vector<char>* normalized, JSContext* cx) {
  // On WASI, we need to collapse ".." path components for the capabilities
  // that we pass to our unit tests to be reasonable; otherwise we need to
  // grant "tests/script1.js/../lib.js" and "tests/script2.js/../lib.js"
  // separately (because the check appears to be a prefix only).
  for (const char* cur = filename; *cur; ++cur) {
    if (std::strncmp(cur, "/../", 4) == 0) {
      do {
        if (normalized->empty()) {
          JS_ReportErrorASCII(cx, "Path processing error");
          return false;
        }
      } while (normalized->popCopy() != '/');
      cur += 2;
      continue;
    }
    if (!normalized->append(*cur)) {
      return false;
    }
  }
  if (!normalized->append('\0')) {
    return false;
  }
  return true;
}
#endif

static FILE* OpenFile(JSContext* cx, const char* filename) {
#ifdef XP_WIN
  JS::UniqueWideChars wideFilename = JS::EncodeUtf8ToWide(cx, filename);
  if (!wideFilename) {
    return nullptr;
  }
  return _wfopen(wideFilename.get(), L"r");
#else
  JS::UniqueChars narrowFilename = JS::EncodeUtf8ToNarrow(cx, filename);
  if (!narrowFilename) {
    return nullptr;
  }
  return fopen(narrowFilename.get(), "r");
#endif
}

/*
 * Open a source file for reading. Supports "-" and nullptr to mean stdin. The
 * return value must be fclosed unless it is stdin.
 */

bool js::AutoFile::open(JSContext* cx, const char* filename) {
  if (!filename || std::strcmp(filename, "-") == 0) {
    fp_ = stdin;
  } else {
#ifdef __wasi__
    js::Vector<char> normalized(cx);
    if (!NormalizeWASIPath(filename, &normalized, cx)) {
      return false;
    }
    fp_ = OpenFile(cx, normalized.begin());
#else
    fp_ = OpenFile(cx, filename);
#endif
    if (!fp_) {
      JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_CANT_OPEN,
                               filename, "No such file or directory");
      return false;
    }
  }
  return true;
}

Messung V0.5
C=91 H=96 G=93

¤ Dauer der Verarbeitung: 0.27 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge