Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  TestingUtility.cpp   Sprache: C

 

/* 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 "builtin/TestingUtility.h"

#ifdef JS_HAS_INTL_API
#  include "mozilla/intl/TimeZone.h"
#endif

#include <stdint.h>  // uint32_t
#include <string.h>

#include "jsapi.h"  // JS_NewPlainObject, JS_WrapValue

#ifdef JS_HAS_INTL_API
#  include "builtin/intl/CommonFunctions.h"
#endif
#include "frontend/CompilationStencil.h"  // js::frontend::CompilationStencil
#include "js/CharacterEncoding.h"         // JS_EncodeStringToUTF8
#include "js/ColumnNumber.h"              // JS::ColumnNumberOneOrigin
#include "js/CompileOptions.h"            // JS::CompileOptions
#include "js/Conversions.h"  // JS::ToBoolean, JS::ToString, JS::ToUint32, JS::ToInt32
#include "js/PropertyAndElement.h"  // JS_GetProperty, JS_DefineProperty
#include "js/PropertyDescriptor.h"  // JSPROP_ENUMERATE
#include "js/RealmOptions.h"        // JS::RealmBehaviors
#include "js/RootingAPI.h"          // JS::Rooted, JS::Handle
#include "js/Utility.h"             // JS::UniqueChars
#include "js/Value.h"               // JS::Value, JS::StringValue
#include "vm/JSContext.h"           // JS::ReportUsageErrorASCII
#include "vm/JSScript.h"
#include "vm/Realm.h"  // JS::Realm

bool js::ParseCompileOptions(JSContext* cx, JS::CompileOptions& options,
                             JS::Handle<JSObject*> opts,
                             JS::UniqueChars* fileNameBytes) {
  JS::Rooted<JS::Value> v(cx);
  JS::Rooted<JSString*> s(cx);

  if (!JS_GetProperty(cx, opts, "isRunOnce", &v)) {
    return false;
  }
  if (!v.isUndefined()) {
    options.setIsRunOnce(JS::ToBoolean(v));
  }

  if (!JS_GetProperty(cx, opts, "noScriptRval", &v)) {
    return false;
  }
  if (!v.isUndefined()) {
    options.setNoScriptRval(JS::ToBoolean(v));
  }

  if (!JS_GetProperty(cx, opts, "fileName", &v)) {
    return false;
  }
  if (v.isNull()) {
    options.setFile(nullptr);
  } else if (!v.isUndefined()) {
    s = JS::ToString(cx, v);
    if (!s) {
      return false;
    }
    if (fileNameBytes) {
      *fileNameBytes = JS_EncodeStringToUTF8(cx, s);
      if (!*fileNameBytes) {
        return false;
      }
      options.setFile(fileNameBytes->get());
    }
  }

  if (!JS_GetProperty(cx, opts, "skipFileNameValidation", &v)) {
    return false;
  }
  if (!v.isUndefined()) {
    options.setSkipFilenameValidation(JS::ToBoolean(v));
  }

  if (!JS_GetProperty(cx, opts, "lineNumber", &v)) {
    return false;
  }
  if (!v.isUndefined()) {
    uint32_t u;
    if (!JS::ToUint32(cx, v, &u)) {
      return false;
    }
    options.setLine(u);
  }

  if (!JS_GetProperty(cx, opts, "columnNumber", &v)) {
    return false;
  }
  if (!v.isUndefined()) {
    int32_t c;
    if (!JS::ToInt32(cx, v, &c)) {
      return false;
    }
    if (c < 1) {
      c = 1;
    }
    options.setColumn(JS::ColumnNumberOneOrigin(c));
  }

  if (!JS_GetProperty(cx, opts, "sourceIsLazy", &v)) {
    return false;
  }
  if (v.isBoolean()) {
    options.setSourceIsLazy(v.toBoolean());
  }

  if (!JS_GetProperty(cx, opts, "forceFullParse", &v)) {
    return false;
  }
  bool forceFullParseIsSet = !v.isUndefined();
  if (v.isBoolean() && v.toBoolean()) {
    options.setForceFullParse();
  }

  if (!JS_GetProperty(cx, opts, "eagerDelazificationStrategy", &v)) {
    return false;
  }
  if (forceFullParseIsSet && !v.isUndefined()) {
    JS_ReportErrorASCII(
        cx, "forceFullParse and eagerDelazificationStrategy are both set.");
    return false;
  }
  if (v.isString()) {
    s = JS::ToString(cx, v);
    if (!s) {
      return false;
    }

    JSLinearString* str = JS_EnsureLinearString(cx, s);
    if (!str) {
      return false;
    }

    bool found = false;
    JS::DelazificationOption strategy = JS::DelazificationOption::OnDemandOnly;

#define MATCH_AND_SET_STRATEGY_(NAME)                       \
  if (!found && JS_LinearStringEqualsLiteral(str, #NAME)) { \
    strategy = JS::DelazificationOption::NAME;              \
    found = true;                                           \
  }

    FOREACH_DELAZIFICATION_STRATEGY(MATCH_AND_SET_STRATEGY_);
#undef MATCH_AND_SET_STRATEGY_
#undef FOR_STRATEGY_NAMES

    if (!found) {
      JS_ReportErrorASCII(cx,
                          "eagerDelazificationStrategy does not match any "
                          "DelazificationOption.");
      return false;
    }
    options.setEagerDelazificationStrategy(strategy);
  }

  return true;
}

bool js::ParseSourceOptions(JSContext* cx, JS::Handle<JSObject*> opts,
                            JS::MutableHandle<JSString*> displayURL,
                            JS::MutableHandle<JSString*> sourceMapURL) {
  JS::Rooted<JS::Value> v(cx);

  if (!JS_GetProperty(cx, opts, "displayURL", &v)) {
    return false;
  }
  if (!v.isUndefined()) {
    displayURL.set(ToString(cx, v));
    if (!displayURL) {
      return false;
    }
  }

  if (!JS_GetProperty(cx, opts, "sourceMapURL", &v)) {
    return false;
  }
  if (!v.isUndefined()) {
    sourceMapURL.set(ToString(cx, v));
    if (!sourceMapURL) {
      return false;
    }
  }

  return true;
}

bool js::SetSourceOptions(JSContext* cx, FrontendContext* fc,
                          ScriptSource* source,
                          JS::Handle<JSString*> displayURL,
                          JS::Handle<JSString*> sourceMapURL) {
  if (displayURL && !source->hasDisplayURL()) {
    JS::UniqueTwoByteChars chars = JS_CopyStringCharsZ(cx, displayURL);
    if (!chars) {
      return false;
    }
    if (!source->setDisplayURL(fc, std::move(chars))) {
      return false;
    }
  }
  if (sourceMapURL && !source->hasSourceMapURL()) {
    JS::UniqueTwoByteChars chars = JS_CopyStringCharsZ(cx, sourceMapURL);
    if (!chars) {
      return false;
    }
    if (!source->setSourceMapURL(fc, std::move(chars))) {
      return false;
    }
  }

  return true;
}

JSObject* js::CreateScriptPrivate(JSContext* cx,
                                  JS::Handle<JSString*> path /* = nullptr */) {
  JS::Rooted<JSObject*> info(cx, NewPlainObjectWithProto(cx, nullptr));
  if (!info) {
    return nullptr;
  }

  if (path) {
    JS::Rooted<JS::Value> pathValue(cx, JS::StringValue(path));
    if (!JS_DefineProperty(cx, info, "path", pathValue, JSPROP_ENUMERATE)) {
      return nullptr;
    }
  }

  return info;
}

bool js::ParseDebugMetadata(JSContext* cx, JS::Handle<JSObject*> opts,
                            JS::MutableHandle<JS::Value> privateValue,
                            JS::MutableHandle<JSString*> elementAttributeName) {
  JS::Rooted<JS::Value> v(cx);
  JS::Rooted<JSString*> s(cx);

  if (!JS_GetProperty(cx, opts, "element", &v)) {
    return false;
  }
  if (v.isObject()) {
    JS::Rooted<JSObject*> infoObject(cx, CreateScriptPrivate(cx));
    if (!infoObject) {
      return false;
    }
    JS::Rooted<JS::Value> elementValue(cx, v);
    if (!JS_WrapValue(cx, &elementValue)) {
      return false;
    }
    if (!JS_DefineProperty(cx, infoObject, "element", elementValue, 0)) {
      return false;
    }
    privateValue.set(JS::ObjectValue(*infoObject));
  }

  if (!JS_GetProperty(cx, opts, "elementAttributeName", &v)) {
    return false;
  }
  if (!v.isUndefined()) {
    s = ToString(cx, v);
    if (!s) {
      return false;
    }
    elementAttributeName.set(s);
  }

  return true;
}

static JS::UniqueChars StringToAscii(JSContext* cx,
                                     JS::Handle<JSObject*> callee,
                                     JS::Handle<JSString*> str) {
  JS::Rooted<JSLinearString*> linear(cx, str->ensureLinear(cx));
  if (!linear) {
    return nullptr;
  }

  if (!StringIsAscii(linear)) {
    ReportUsageErrorASCII(cx, callee,
                          "First argument contains non-ASCII characters");
    return nullptr;
  }

  return JS_EncodeStringToASCII(cx, linear);
}

JS::UniqueChars js::StringToLocale(JSContext* cx, JS::Handle<JSObject*> callee,
                                   JS::Handle<JSString*> str) {
  UniqueChars locale = StringToAscii(cx, callee, str);
  if (!locale) {
    return nullptr;
  }

  bool containsOnlyValidBCP47Characters =
      mozilla::IsAsciiAlpha(locale[0]) &&
      std::all_of(locale.get(), locale.get() + str->length(), [](auto c) {
        return mozilla::IsAsciiAlphanumeric(c) || c == '-';
      });

  if (!containsOnlyValidBCP47Characters) {
    ReportUsageErrorASCII(cx, callee,
                          "First argument should be a BCP47 language tag");
    return nullptr;
  }

  return locale;
}

/*
 * Validate time zone input. Accepts the following formats:
 *  - "America/Chicago" (raw time zone)
 *  - ":America/Chicago"
 *  - "/this-part-is-ignored/zoneinfo/America/Chicago"
 *  - ":/this-part-is-ignored/zoneinfo/America/Chicago"
 *  - "/etc/localtime"
 *  - ":/etc/localtime"
 * Once the raw time zone is parsed out of the string, it is checked
 * against the time zones from GetAvailableTimeZones(). Throws an
 * Error if the time zone is invalid.
 */

static bool ValidateTimeZone(JSContext* cx, const char* timeZone,
                             js::AllowTimeZoneLink allowLink) {
  const char* timeZonePart;
  if (allowLink == js::AllowTimeZoneLink::Yes) {
    static constexpr char zoneInfo[] = "/zoneinfo/";
    static constexpr size_t zoneInfoLength = sizeof(zoneInfo) - 1;

    size_t i = 0;
    if (timeZone[i] == ':') {
      ++i;
    }
    const char* zoneInfoPtr = strstr(timeZone, zoneInfo);
    timeZonePart = timeZone[i] == '/' && zoneInfoPtr
                       ? zoneInfoPtr + zoneInfoLength
                       : timeZone + i;
    if (!*timeZonePart) {
      JS_ReportErrorASCII(cx, "Invalid time zone format");
      return false;
    }

    if (!strcmp(timeZonePart, "/etc/localtime")) {
      return true;
    }
  } else {
    timeZonePart = timeZone;
  }

#if defined(JS_HAS_INTL_API) && !defined(__wasi__)
  auto timeZones = mozilla::intl::TimeZone::GetAvailableTimeZones();
  if (timeZones.isErr()) {
    js::intl::ReportInternalError(cx, timeZones.unwrapErr());
    return false;
  }
  for (auto timeZoneName : timeZones.unwrap()) {
    if (timeZoneName.isErr()) {
      js::intl::ReportInternalError(cx);
      return false;
    }

    if (!strcmp(timeZonePart, timeZoneName.unwrap().data())) {
      return true;
    }
  }

  JS_ReportErrorASCII(cx, "Unsupported time zone name: %s", timeZonePart);
  return false;
#else
  return true;
#endif
}

JS::UniqueChars js::StringToTimeZone(JSContext* cx,
                                     JS::Handle<JSObject*> callee,
                                     JS::Handle<JSString*> str,
                                     AllowTimeZoneLink allowLink) {
  UniqueChars timeZone = StringToAscii(cx, callee, str);
  if (!timeZone) {
    return nullptr;
  }

  if (!ValidateTimeZone(cx, timeZone.get(), allowLink)) {
    return nullptr;
  }

  return timeZone;
}

bool js::ValidateLazinessOfStencilAndGlobal(JSContext* cx,
                                            const JS::Stencil* stencil) {
  if (cx->realm()->behaviors().discardSource() && stencil->canLazilyParse()) {
    JS_ReportErrorASCII(cx,
                        "Stencil compiled with with lazy parse option cannot "
                        "be used in a realm with discardSource");
    return false;
  }

  return true;
}

bool js::ValidateModuleCompileOptions(JSContext* cx,
                                      JS::CompileOptions& options) {
  if (options.lineno == 0) {
    JS_ReportErrorASCII(cx, "Module cannot be compiled with lineNumber == 0");
    return false;
  }

  if (!options.filename()) {
    JS_ReportErrorASCII(cx, "Module should have filename");
    return false;
  }

  return true;
}

Messung V0.5 in Prozent
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

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

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1127926
#Domains=2039723