]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Expose sqlite3_randomness() to WASM and add a custom binding for it which can populat...
authorstephan <stephan@noemail.net>
Thu, 27 Oct 2022 03:03:16 +0000 (03:03 +0000)
committerstephan <stephan@noemail.net>
Thu, 27 Oct 2022 03:03:16 +0000 (03:03 +0000)
FossilOrigin-Name: 333e67076b4bc967bb543ef8e265c63f6e3498c38ac121a7d1eff4a1d7a71c63

ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api
ext/wasm/api/sqlite3-api-glue.js
ext/wasm/api/sqlite3-api-prologue.js
ext/wasm/common/whwasmutil.js
ext/wasm/tester1.js
manifest
manifest.uuid

index b31f613576975cef13d62543ecaf4fb6aa54db17..416b08d23ff9b954859f846fb00ac0ad4c80b49e 100644 (file)
@@ -52,6 +52,7 @@ _sqlite3_open
 _sqlite3_open_v2
 _sqlite3_prepare_v2
 _sqlite3_prepare_v3
+_sqlite3_randomness
 _sqlite3_realloc
 _sqlite3_realloc64
 _sqlite3_reset
index 639e670792466e8d112fa7ce176b81b15a35a529..d096af1c89b98c510f4361bb3d77439e07a4a9f2 100644 (file)
@@ -45,7 +45,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       if(v && v.constructor && v instanceof StructBinder.StructType){
         v = v.pointer;
       }
-      return (v === (v | 0) /* v is a 32-bit integer */)
+      return wasm.isPtr(v)
         ? argPointer(v)
         : toss("Invalid (object) type for StructType-type argument.");
     });
index 1fcc9a64abce59e7a2fae734ad4754650d615f8c..71058d174e3f67395606b8a93b14045a370f0a64 100644 (file)
@@ -215,6 +215,32 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     return (v && v.constructor && isInt32(v.constructor.BYTES_PER_ELEMENT)) ? v : false;
   };
 
+
+  /** Internal helper to use in operations which need to distinguish
+      between TypedArrays which are backed by a SharedArrayBuffer
+      from those which are not. */
+  const __SAB = ('undefined'===typeof SharedArrayBuffer)
+        ? function(){} : SharedArrayBuffer;
+  /** Returns true if the given TypedArray object is backed by a
+      SharedArrayBuffer, else false. */
+  const isSharedTypedArray = (aTypedArray)=>(aTypedArray.buffer instanceof __SAB);
+
+  /**
+     Returns either aTypedArray.slice(begin,end) (if
+     aTypedArray.buffer is a SharedArrayBuffer) or
+     aTypedArray.subarray(begin,end) (if it's not).
+
+     This distinction is important for APIs which don't like to
+     work on SABs, e.g. TextDecoder, and possibly for our
+     own APIs which work on memory ranges which "might" be
+     modified by other threads while it's working.
+   */
+  const typedArrayPart = (aTypedArray, begin, end)=>{
+    return isSharedTypedArray(aTypedArray)
+      ? aTypedArray.slice(begin, end)
+      : aTypedArray.subarray(begin, end);
+  };
+
   /**
      Returns true if v appears to be one of our bind()-able
      TypedArray types: Uint8Array or Int8Array. Support for
@@ -246,16 +272,16 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
 
   const utf8Decoder = new TextDecoder('utf-8');
 
-  /** Internal helper to use in operations which need to distinguish
-      between SharedArrayBuffer heap memory and non-shared heap. */
-  const __SAB = ('undefined'===typeof SharedArrayBuffer)
-        ? function(){} : SharedArrayBuffer;
-  const typedArrayToString = function(arrayBuffer, begin, end){
-    return utf8Decoder.decode(
-      (arrayBuffer.buffer instanceof __SAB)
-        ? arrayBuffer.slice(begin, end)
-        : arrayBuffer.subarray(begin, end)
-    );
+  /**
+     Uses TextDecoder to decode the given half-open range of the
+     given TypedArray to a string. This differs from a simple
+     call to TextDecoder in that it accounts for whether the
+     first argument is based by a SharedArrayBuffer or not,
+     and can work more efficiently if it's not (TextDecoder
+     refuses to act upon an SAB).
+  */
+  const typedArrayToString = function(typedArray, begin, end){
+    return utf8Decoder.decode(typedArrayPart(typedArray, begin,end));
   };
 
   /**
@@ -502,11 +528,11 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
 
        If the callback is a function, then for the duration of the
        sqlite3_exec() call, it installs a WASM-bound function which
-       acts as a proxy for the given callback. That proxy will
-       also perform a conversion of the callback's arguments from
+       acts as a proxy for the given callback. That proxy will also
+       perform a conversion of the callback's arguments from
        `(char**)` to JS arrays of strings. However, for API
-       consistency's sake it will still honor the C-level
-       callback parameter order and will call it like:
+       consistency's sake it will still honor the C-level callback
+       parameter order and will call it like:
 
        `callback(pVoid, colCount, listOfValues, listOfColNames)`
 
@@ -517,12 +543,27 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     */
     sqlite3_exec: (pDb, sql, callback, pVoid, pErrMsg)=>{}/*installed later*/,
 
+    /**
+       If passed a single argument which appears to be a byte-oriented
+       TypedArray (Int8Array or Uint8Array), this function treats that
+       TypedArray as an output target, fetches `theArray.byteLength`
+       bytes of randomness, and populates the whole array with it. As
+       a special case, if the array's length is 0, this function
+       behaves as if it were passed (0,0). When called this way, it
+       returns its argument, else it returns the `undefined` value.
+
+       If called with any other arguments, they are passed on as-is
+       to the C API. Results are undefined if passed any incompatible
+       values.
+     */
+    sqlite3_randomness: (n, outPtr)=>{/*installed later*/},
+
     /**
        Various internal-use utilities are added here as needed. They
        are bound to an object only so that we have access to them in
        the differently-scoped steps of the API bootstrapping
        process. At the end of the API setup process, this object gets
-       removed.
+       removed. These are NOT part of the public API.
     */
     util:{
       affirmBindableTypedArray, flexibleString,
@@ -530,7 +571,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
       isBindableTypedArray,
       isInt32, isSQLableTypedArray, isTypedArray, 
       typedArrayToString,
-      isUIThread: ()=>'undefined'===typeof WorkerGlobalScope
+      isUIThread: ()=>'undefined'===typeof WorkerGlobalScope,
+      isSharedTypedArray,
+      typedArrayPart
     },
     
     /**
@@ -617,7 +660,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     }/*wasm*/
   }/*capi*/;
 
-  const wasm = capi.wasm;
+  const wasm = capi.wasm, util = capi.util;
 
   /**
      wasm.alloc()'s srcTypedArray.byteLength bytes,
@@ -743,8 +786,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     // Please keep these sorted by function name!
     ["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
     ["sqlite3_bind_blob","int", "sqlite3_stmt*", "int", "*", "int", "*"
-     /* We should arguably write a custom wrapper which knows how
-        to handle Blob, TypedArrays, and JS strings. */
+     /* TODO: we should arguably write a custom wrapper which knows
+        how to handle Blob, TypedArrays, and JS strings. */
     ],
     ["sqlite3_bind_double","int", "sqlite3_stmt*", "int", "f64"],
     ["sqlite3_bind_int","int", "sqlite3_stmt*", "int", "int"],
@@ -752,10 +795,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     ["sqlite3_bind_parameter_count", "int", "sqlite3_stmt*"],
     ["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"],
     ["sqlite3_bind_text","int", "sqlite3_stmt*", "int", "string", "int", "int"
-     /* We should arguably create a hand-written binding
-        which does more flexible text conversion, along the lines of
-        sqlite3_prepare_v3(). The slightly problematic part is the
-        final argument (text destructor). */
+     /* We should arguably create a hand-written binding of
+        bind_text() which does more flexible text conversion, along
+        the lines of sqlite3_prepare_v3(). The slightly problematic
+        part is the final argument (text destructor). */
     ],
     ["sqlite3_close_v2", "int", "sqlite3*"],
     ["sqlite3_changes", "int", "sqlite3*"],
@@ -770,15 +813,16 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     ["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
     ["sqlite3_compileoption_get", "string", "int"],
     ["sqlite3_compileoption_used", "int", "string"],
-    /* sqlite3_create_function_v2() is handled separate to simplify conversion
-       of its callback argument */
+    /* sqlite3_create_function(), sqlite3_create_function_v2(), and
+       sqlite3_create_window_function() use hand-written bindings to
+       simplify handling of their function-type arguments. */
     ["sqlite3_data_count", "int", "sqlite3_stmt*"],
     ["sqlite3_db_filename", "string", "sqlite3*", "string"],
     ["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"],
     ["sqlite3_db_name", "string", "sqlite3*", "int"],
     ["sqlite3_deserialize", "int", "sqlite3*", "string", "*", "i64", "i64", "int"]
     /* Careful! Short version: de/serialize() are problematic because they
-       might use a different allocator that the user for managing the
+       might use a different allocator than the user for managing the
        deserialized block. de/serialize() are ONLY safe to use with
        sqlite3_malloc(), sqlite3_free(), and its 64-bit variants. */,
     ["sqlite3_errmsg", "string", "sqlite3*"],
@@ -806,6 +850,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     /* sqlite3_prepare_v2() and sqlite3_prepare_v3() are handled
        separately due to us requiring two different sets of semantics
        for those, depending on how their SQL argument is provided. */
+    /* sqlite3_randomness() uses a hand-written wrapper to extend
+       the range of supported argument types. */
     ["sqlite3_realloc", "*","*","int"],
     ["sqlite3_reset", "int", "sqlite3_stmt*"],
     ["sqlite3_result_blob",undefined, "*", "*", "int", "*"],
@@ -1052,8 +1098,41 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     throw new SQLite3Error(...args);
   };
 
+  capi.sqlite3_randomness = (...args)=>{
+    if(1===args.length && util.isTypedArray(args[0])
+      && 1===args[0].BYTES_PER_ELEMENT){
+      const ta = args[0];
+      if(0===ta.byteLength){
+        wasm.exports.sqlite3_randomness(0,0);
+        return ta;
+      }
+      const stack = wasm.pstack.pointer;
+      try {
+        let n = ta.byteLength, offset = 0;
+        const r = wasm.exports.sqlite3_randomness;
+        const heap = wasm.heap8u();
+        const nAlloc = n < 512 ? n : 512;
+        const ptr = wasm.pstack.alloc(nAlloc);
+        do{
+          const j = (n>nAlloc ? nAlloc : n);
+          r(j, ptr);
+          ta.set(typedArrayPart(heap, ptr, ptr+j), offset);
+          n -= j;
+          offset += j;
+        } while(n > 0);
+      }catch(e){
+        console.error("Highly unexpected (and ignored!) "+
+                      "exception in sqlite3_randomness():",e);
+      }finally{
+        wasm.pstack.restore(stack);
+      }
+      return ta;
+    }
+    capi.wasm.exports.sqlite3_randomness(...args);
+  };
+
   /** State for sqlite3_wasmfs_opfs_dir(). */
-  let __persistentDir = undefined;
+  let __wasmfsOpfsDir = undefined;
   /**
      If the wasm environment has a WASMFS/OPFS-backed persistent
      storage directory, its path is returned by this function. If it
@@ -1068,26 +1147,26 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
      Emscripten-managed virtual filesystem.
   */
   capi.sqlite3_wasmfs_opfs_dir = function(){
-    if(undefined !== __persistentDir) return __persistentDir;
+    if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
     // If we have no OPFS, there is no persistent dir
     const pdir = config.wasmfsOpfsDir;
     if(!pdir
        || !self.FileSystemHandle
        || !self.FileSystemDirectoryHandle
        || !self.FileSystemFileHandle){
-      return __persistentDir = "";
+      return __wasmfsOpfsDir = "";
     }
     try{
       if(pdir && 0===wasm.xCallWrapped(
         'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
       )){
-        return __persistentDir = pdir;
+        return __wasmfsOpfsDir = pdir;
       }else{
-        return __persistentDir = "";
+        return __wasmfsOpfsDir = "";
       }
     }catch(e){
       // sqlite3_wasm_init_wasmfs() is not available
-      return __persistentDir = "";
+      return __wasmfsOpfsDir = "";
     }
   };
 
index e04886de8ab60766f961a85a986a22ae47517c46..24c67ef78f6f209d842c85fa8fd99e7f5b1fae8b 100644 (file)
@@ -704,6 +704,23 @@ self.WhWasmUtilInstaller = function(target){
       pointer-to-pointer values. */
   target.setPtrValue = (ptr, value)=>target.setMemValue(ptr, value, ptrIR);
 
+  /**
+     Returns true if the given value appears to be legal for use as
+     a WASM pointer value. Its _range_ of values is not (cannot be)
+     validated except to ensure that it is a 32-bit integer with a
+     value of 0 or greater. Likewise, it cannot verify whether the
+     value actually refers to allocated memory in the WASM heap.
+  */
+  target.isPtr32 = (ptr)=>('number'===typeof ptr && (ptr===(ptr|0)) && ptr>=0);
+
+  /**
+     isPtr() is an alias for isPtr32(). If/when 64-bit WASM pointer
+     support becomes widespread, it will become an alias for either
+     isPtr32() or the as-yet-hypothetical isPtr64(), depending on a
+     configuration option.
+  */
+  target.isPtr = target.isPtr32;
+
   /**
      Expects ptr to be a pointer into the WASM heap memory which
      refers to a NUL-terminated C-style string encoded as UTF-8.
@@ -1229,7 +1246,8 @@ self.WhWasmUtilInstaller = function(target){
   xcv.result['*'] = xcv.result['pointer'] = xcv.arg['**'] = xcv.arg[ptrIR];
   xcv.result['number'] = (v)=>Number(v);
 
-  {
+  { /* Copy certain xcv.arg[...] handlers to xcv.result[...] and
+       add pointer-style variants of them. */
     const copyToResult = ['i8', 'i16', 'i32', 'int',
                           'f32', 'float', 'f64', 'double'];
     if(target.bigIntEnabled) copyToResult.push('i64');
index 4a6074d91bc6f100f7b00254b67aa2a4c7136bba..d3f1c44fc507852c0035d55c11c976b81afa3543 100644 (file)
         }
       }
 
+      // isPtr32()
+      {
+        const ip = w.isPtr32;
+        T.assert(ip(0))
+          .assert(!ip(-1))
+          .assert(!ip(1.1))
+          .assert(!ip(0xffffffff))
+          .assert(ip(0x7fffffff))
+          .assert(!ip())
+          .assert(!ip(null)/*might change: under consideration*/)
+        ;
+      }
+
       //log("jstrlen()...");
       {
         T.assert(3 === w.jstrlen("abc")).assert(4 === w.jstrlen("äbc"));
   ////////////////////////////////////////////////////////////////////
   ;/*end of C/WASM utils checks*/
 
+  T.g('sqlite3_randomness()')
+    .t('To memory buffer', function(sqlite3){
+      const stack = wasm.pstack.pointer;
+      try{
+        const n = 520;
+        const p = wasm.pstack.alloc(n);
+        T.assert(0===wasm.getMemValue(p))
+          .assert(0===wasm.getMemValue(p+n-1));
+        T.assert(undefined === capi.sqlite3_randomness(n - 10, p));
+        let j, check = 0;
+        const heap = wasm.heap8u();
+        for(j = 0; j < 10 && 0===check; ++j){
+          check += heap[p + j];
+        }
+        T.assert(check > 0);
+        check = 0;
+        // Ensure that the trailing bytes were not modified...
+        for(j = n - 10; j < n && 0===check; ++j){
+          check += heap[p + j];
+        }
+        T.assert(0===check);
+      }finally{
+        wasm.pstack.restore(stack);
+      }
+    })
+    .t('To byte array', function(sqlite3){
+      const ta = new Uint8Array(117);
+      let i, n = 0;
+      for(i=0; i<ta.byteLength && 0===n; ++i){
+        n += ta[i];
+      }
+      T.assert(0===n)
+        .assert(ta === capi.sqlite3_randomness(ta));
+      for(i=ta.byteLength-10; i<ta.byteLength && 0===n; ++i){
+        n += ta[i];
+      }
+      T.assert(n>0);
+      const t0 = new Uint8Array(0);
+      T.assert(t0 === capi.sqlite3_randomness(t0),
+               "0-length array is a special case");
+    })
+  ;;/*end sqlite3_randomness() checks*/
+
   ////////////////////////////////////////////////////////////////////////
   T.g('sqlite3.oo1')
     .t('Create db', function(sqlite3){
index 1ba4ebfcf90420281dc424713ffe17065cd66f4a..4c7e6bd1425ddf49160d2f8717ac8411605f5b46 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Disable\sthe\spush-down\soptimization\sfor\ssub-queries\sthat\sare\sINTERSECT,\sUNION\sor\sEXCEPT\scompounds.\sdbsqlfuzz\sa34f455c91ad75a0cf8cd9476841903f42930a7a.
-D 2022-10-26T21:14:21.853
+C Expose\ssqlite3_randomness()\sto\sWASM\sand\sadd\sa\scustom\sbinding\sfor\sit\swhich\scan\spopulate\sa\sJS\sbyte\sarray.\sAdd\sWhWasmUtil.isPtr().
+D 2022-10-27T03:03:16.460
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -490,7 +490,7 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce
 F ext/wasm/GNUmakefile 7a8c06f9bdbb791f8ef084ecd47e099da81e5797b9b1d60e33ac9a07eedd5dbd
 F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20
 F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8a3066
-F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 36f413ab4dbb057d2dec938fb366ac0a4c5e85ba14660a8d672f0277602c0fc5
+F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api cfbe8efcb9d1444139d6c381eb54dfdd5e62cf1ddfe10ed8a38617149a664b9b
 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
 F ext/wasm/api/README.md 1350088aee90e959ad9a94fab1bb6bcb5e99d4d27f976db389050f54f2640c78
 F ext/wasm/api/extern-post-js.js 926d192b72fa808378e5e7843721dc7ba3908c163a0260e06d8aa501c12f5469
@@ -499,10 +499,10 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08
 F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
 F ext/wasm/api/pre-js.js 151e0616614a49f3db19ed544fa13b38c87c108959fbcd4029ea8399a562d94f
 F ext/wasm/api/sqlite3-api-cleanup.js 4d07a7524dc9b7b050acfde57163e839243ad2383bd7ee0de0178b1b3e988588
-F ext/wasm/api/sqlite3-api-glue.js 6e4e472eb5afc732a695cd7c5ded6dee6ef8b480e61aa0d648a3fc9033c84745
+F ext/wasm/api/sqlite3-api-glue.js f024dc2f41418ad203edf1228d7cf7934249c11ffcbb65d21f9bb69333d63d55
 F ext/wasm/api/sqlite3-api-oo1.js 38004e18001396c078124769e14737a0ff703f98317279734020121af72efdd5
 F ext/wasm/api/sqlite3-api-opfs.js 62da8b7cac30d4e7bb940762d2ac948b0aeb89704a5a290b74eb268ecbd1a64e
-F ext/wasm/api/sqlite3-api-prologue.js fa00d55f927e5a4ec51cf2c80f6f0eaed2f4f5774341ecf3d63a0ea4c738f8f5
+F ext/wasm/api/sqlite3-api-prologue.js 4706ca7fa125426019b8dd01f9e6a774021a2781874df8b9f435c69544383e79
 F ext/wasm/api/sqlite3-api-worker1.js b2d650514ccc75f80dff666fd3ee68dc8fb4137bcd01caac2c62ff93a7ebf638
 F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
 F ext/wasm/api/sqlite3-opfs-async-proxy.js f04cb1eb483c92bc61fe02749f7afcf17ec803968171aedd7d96faf428c26bcb
@@ -515,7 +515,7 @@ F ext/wasm/batch-runner.js 5bae81684728b6be157d1f92b39824153f0fd019345b39f2ab893
 F ext/wasm/common/SqliteTestUtil.js 647bf014bd30bdd870a7e9001e251d12fc1c9ec9ce176a1004b838a4b33c5c05
 F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
 F ext/wasm/common/testing.css 739b58c44511f642f16f57b701c84dc9ee412d8bc47b3d8a99d947babfa69d9d
-F ext/wasm/common/whwasmutil.js 50d2ede0b0fa01c1d467e1801fab79f5e46bb02bcbd2b0232e4fdc6090a47818
+F ext/wasm/common/whwasmutil.js 77930367c2a65cf6fd6f99ad3644ede33e4d20466f5e506eb87b8d101a0a7655
 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
 F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
 F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
@@ -548,7 +548,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
 F ext/wasm/test-opfs-vfs.js 48fc59110e8775bb43c9be25b6d634fc07ebadab7da8fbd44889e8129c6e2548
 F ext/wasm/tester1-worker.html d02b9d38876b023854cf8955e77a40912f7e516956b4dbe1ec7f215faac273ee
 F ext/wasm/tester1.html c6c47e5a8071eb09cb1301104435c8e44fbb5719c92411f5b2384a461f9793c5
-F ext/wasm/tester1.js 21dad63165954a8a28dfa8eeab68a4881eb1d9b5c6bc9f2c83aa3ceea8c41fee
+F ext/wasm/tester1.js 39dd4277944f79f475d78850ebbf48b0fe61b2caf4df2b5c5db6219f509d5c96
 F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
 F ext/wasm/wasmfs.make ee0004813e16c283ff633e08b482008d56adf9b7d42f6c5612f7ab002b924f69
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
@@ -2052,8 +2052,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P a029dddff4f4ed7275538610cbd9cea658b905b72924860ec9cda9e76dabcfac
-R b53abb7e437a17a51c11b8e565290cc0
-U dan
-Z f234279171f2df9582a4a9e673101d04
+P 346a3b12b861ce7ba369e98cd336f79a1d4f7a7bb9acd7a4f63f37b391755bf5
+R 5867ff413088cae7742d2b15dc451b3e
+U stephan
+Z c456212142f768a2abd7eb0069fb1a57
 # Remove this line to create a well-formed Fossil manifest.
index 3ad43b42ae96e370dfd3a53e0056de1b9926496d..db063108c15239f37c9aa25952bd5bc65adc8402 100644 (file)
@@ -1 +1 @@
-346a3b12b861ce7ba369e98cd336f79a1d4f7a7bb9acd7a4f63f37b391755bf5
\ No newline at end of file
+333e67076b4bc967bb543ef8e265c63f6e3498c38ac121a7d1eff4a1d7a71c63
\ No newline at end of file