Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  test_KeyedUUIDMapper.js

  Sprache: JAVA
 

/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */


"use strict";

const KeyedUUIDMapper = Components.Constructor(
  "@mozilla.org/keyed-uuid-mapper;1",
  Ci.nsIKeyedUUIDMapper,
  "init"
);

function makeMapper(seed) {
  // Some key - the specifics do not matter, as long as it is 16 bytes.
  const key = new Uint8Array(16).map((_, i) => (seed + i) & 0xff);
  return new KeyedUUIDMapper(key);
}

// NOTE: All test tasks here are run twice, first in the parent process as
// usual, and then again in the content process in the end as a double check,
// via test_KeyedUUIDMapper_in_content_process.

add_task(function test_generateKey() {
  const mapper = Cc["@mozilla.org/keyed-uuid-mapper;1"].createInstance(
    Ci.nsIKeyedUUIDMapper
  );
  const key1 = mapper.generateKey();

  const key2 = Cc["@mozilla.org/keyed-uuid-mapper;1"]
    .createInstance(Ci.nsIKeyedUUIDMapper)
    .generateKey();

  Assert.equal(key1.length, key2.length, "Keys have consistent lengths");
  Assert.ok(
    key1.some((v, i) => v !== key2[i]),
    "generateKey() returns unique key"
  );

  Assert.throws(
    () => mapper.toUUID(1),
    /NS_ERROR_NOT_INITIALIZED/,
    "generateKey() does not initialize mapper"
  );
  mapper.init(key2);
  Assert.ok(mapper.toUUID(1), "generateKey() result can initialize mapper");
});

add_task(function test_uuid_format() {
  const UUID_RE =
    /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;

  const result = makeMapper(1).toUUID(1);

  Assert.ok(UUID_RE.test(result), "toUUID() returns a lowercase UUID string");
  // The exact value does not matter, we just check a specific value to make
  // sure that the output is reasonably stable.
  Assert.equal(result, "c047bf20-c07c-9531-7e69-e6d65bf96acd""Stable uuid");
  // If you ever need to change the above expectation, that means that you are
  // changing the algorithm. The test_invalid_uuid test tests a boundary case
  // that you have to re-generate, as follows:
  // 1. Disable kJS_MAX_SAFE_UINTEGER constraint in KeyedUUIDMapper::ToUUID.
  // 2. Uncomment the following line:
  //    Assert.ok(false, makeMapper(1).toUUID(Number.MAX_SAFE_INTEGER + 1));
  // 3. Run this test, and copy the displayed UUID.
  // 4. Replace test_invalid_uuid's MAX_SAFE_INTEGER+1 test case with it.
});

add_task(function test_roundtrip() {
  for (const [seed, value] of [
    [00],
    [11],
    [0xde, 42],
    [0x12, 0xabcdef],
    [0x7f, Number.MAX_SAFE_INTEGER],
  ]) {
    const mapper = makeMapper(seed);
    Assert.equal(
      mapper.fromUUID(mapper.toUUID(value)),
      value,
      `seed=${seed}, value=${value}`
    );
  }
});

add_task(function test_toUUID_max_range() {
  const mapper = makeMapper(1);
  // Beyond MAX_SAFE_INTEGER some numbers may not accurately be represented
  // in JS. E.g., 2*63 is 9223372036854775808, but ends with 776 000 instead.
  // The implementation explicitly filters those to avoid loss of precision.
  Assert.throws(
    () => mapper.toUUID(Number.MAX_SAFE_INTEGER + 1),
    // NS_ERROR_INVALID_ARG is converted to NS_ERROR_ILLEGAL_VALUE:
    /NS_ERROR_ILLEGAL_VALUE/,
    "toUUID rejects number past MAX_SAFE_INTEGER"
  );
  Assert.throws(
    () => mapper.toUUID(2 ** 63),
    // NS_ERROR_INVALID_ARG is converted to NS_ERROR_ILLEGAL_VALUE:
    /NS_ERROR_ILLEGAL_VALUE/,
    "toUUID rejects number past MAX_SAFE_INTEGER"
  );

  // Note: values beyond Number.MAX_SAFE_INTEGER are rejected, as shown above.
  // But beyond the 64-bit numeric range the values become 0 before the
  // implementation event receives the value.
  Assert.equal(
    mapper.fromUUID(mapper.toUUID(2 ** 66)),
    0,
    "toUUID does not support numbers outside the 64-bit range"
  );
});

add_task(function test_opaque_without_key() {
  const uuid = makeMapper(0xca).toUUID(0xbabe);
  // With a different key 0xcb, we should not get value 0xbabe back.
  // In fact, because 0xbabe is not a value that could ever have been produced
  // for this given UUID, the implementation throws:
  Assert.throws(
    () => makeMapper(0xcb).fromUUID(uuid),
    /NS_ERROR_ILLEGAL_VALUE/,
    "wrong key does not recover the original value"
  );
});

add_task(function test_case_insensitive_parsing() {
  const lower = makeMapper(1).toUUID(42);
  const upper = makeMapper(1).toUUID(42).toUpperCase();
  Assert.notEqual(lower, upper, "Contains alpha characters");
  const mapper = makeMapper(1);
  Assert.equal(mapper.fromUUID(upper), 42"fromUUID accepts uppercase hex");
});

add_task(function test_reinit() {
  const mapper = makeMapper(1);
  const uuid1 = mapper.toUUID(42);
  mapper.init(new Uint8Array(16).fill(0xff));
  Assert.notEqual(
    mapper.toUUID(42),
    uuid1,
    "reinit with new key changes output"
  );
  mapper.init(new Uint8Array(16).map((_, i) => (1 + i) & 0xff));
  Assert.equal(
    mapper.toUUID(42),
    uuid1,
    "reinit with original key restores output"
  );
});

add_task(function test_not_initialized() {
  const mapper = Cc["@mozilla.org/keyed-uuid-mapper;1"].createInstance(
    Ci.nsIKeyedUUIDMapper
  );
  // Note: mapper.init() not called.
  Assert.throws(() => mapper.toUUID(1), /NS_ERROR_NOT_INITIALIZED/);
  Assert.throws(
    () => mapper.fromUUID("00000000-0000-0000-0000-000000000000"),
    /NS_ERROR_NOT_INITIALIZED/
  );
});

add_task(function test_invalid_key_size() {
  const mapper = Cc["@mozilla.org/keyed-uuid-mapper;1"].createInstance(
    Ci.nsIKeyedUUIDMapper
  );
  for (const keyLength of [0151732]) {
    Assert.throws(
      () => mapper.init(new Uint8Array(keyLength)),
      // NS_ERROR_INVALID_ARG is converted to NS_ERROR_ILLEGAL_VALUE:
      /NS_ERROR_ILLEGAL_VALUE/,
      `rejects key of length ${keyLength}`
    );
  }
});

add_task(function test_invalid_uuid() {
  const mapper = makeMapper(1);
  for (const bad of [
    "",
    "not-a-uuid",
    "00000000-0000-0000-0000-00000000000"// too short
    "00000000-0000-0000-0000-0000000000000"// too long
    "00000000-0000-0000-0000-00000000000g"// invalid hex char
    "000000000000-0000-0000-0000-000000000000"// wrong dash positions
    // Right length, but no value maps to this. If one inputs a random UUID,
    // they are in fact more likely going to get an error than a mapping to
    // an arbitrary value because there are 2^128 UUIDs but only 2^64 valid
    // values.
    "00000000-0000-0000-0000-000000000000",
    // The generated UUID for MAX_SAFE_INTEGER+1 (9007199254740992),
    // if the implementation would not have capped it at MAX_SAFE_INTEGER.
    "31bf73c9-08ba-c9b8-1fb7-922e1f311eb4",
    "{" + mapper.toUUID(1) + "}"// Reject UUID with brackets.
  ]) {
    Assert.throws(
      () => mapper.fromUUID(bad),
      // NS_ERROR_INVALID_ARG is converted to NS_ERROR_ILLEGAL_VALUE:
      /NS_ERROR_ILLEGAL_VALUE/,
      `rejects invalid uuid: "${bad}"`
    );
  }
});

add_task(function test_fromUUID_non_ascii() {
  const mapper = makeMapper(0xde);
  const uuid = mapper.toUUID(42);
  // ^ test_roundtrip already verified that fromUUID(uuid) will return 42.

  // String where the lossy conversion from UTF16 to ASCII would be identical
  // to the input, but which actually differs from the real input.
  const bad = String.fromCharCode(uuid.charCodeAt(0) + 0x100) + uuid.slice(1);
  Assert.throws(
    () => mapper.fromUUID(bad),
    // NS_ERROR_INVALID_ARG is converted to NS_ERROR_ILLEGAL_VALUE:
    /NS_ERROR_ILLEGAL_VALUE/,
    "Rejects non-ASCII"
  );
});

// Internally, the mapping is implemented with AES 128. This is merely an
// implementation detail. However, we verify that that the behavior matches.
// This proof ensures that the mapper inherits these desired properties:
// - Confidentiality: Value cannot be recovered from UUID without key.
// - Deterministic: For the same sets of inputs, the result is identical.
// - Unique: Every input value produces an unique UUID.
// - Reversable: A UUID can be mapped back (AES encrypt <-> decrypt).
add_task(async function test_verify_alg_AES_128() {
  // Some arbitrary test values.
  const keyBytes = new Uint8Array(16).fill(128);
  const value = 0x123456789;
  // crypto.subtle does not support AES-ECB, but for the first block it is
  // equivalent to AES-CBC with a zero IV, so we can use that for verification.
  const AES_ALGO = "AES-CBC";

  const key = await crypto.subtle.importKey(
    "raw",
    keyBytes,
    { name: AES_ALGO },
    false,
    ["encrypt"]
  );
  const plaintext = new Uint8Array(16);
  new DataView(plaintext.buffer).setBigUint64(0, BigInt(value));

  const raw = await crypto.subtle.encrypt(
    { name: AES_ALGO, iv: new Uint8Array(16) },
    key,
    plaintext
  );
  const uuidBytes = new Uint8Array(raw, 016); // drop padding

  Assert.equal(
    new KeyedUUIDMapper(keyBytes).toUUID(value).replaceAll("-"""),
    uuidBytes.toHex(),
    "KeyedUUIDMapper mapping is equivalent to AES-ECB"
  );
});

if (runningInParent) {
  // Run same tests again, but in the content process.
  add_task(async function test_KeyedUUIDMapper_in_content_process() {
    await run_test_in_child("test_KeyedUUIDMapper.js");
  });
}

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

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© 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=277311
#Domains=752002