@@ -19,7 +19,7 @@ if (__DEV__) {
1919var React = require ( "react" ) ;
2020var ReactDOM = require ( "react-dom" ) ;
2121
22- var ReactVersion = "18.3.0-www-classic-e2d232ce " ;
22+ var ReactVersion = "18.3.0-www-classic-24cad190 " ;
2323
2424// This refers to a WWW module.
2525var warningWWW = require ( "warning" ) ;
@@ -81,6 +81,115 @@ function printWarning(level, format, args) {
8181 }
8282}
8383
84+ // A pure JS implementation of a string hashing function. We do not use it for
85+ // security or obfuscation purposes, only to create compact hashes. So we
86+ // prioritize speed over collision avoidance. For example, we use this to hash
87+ // the component key path used by useFormState for MPA-style submissions.
88+ //
89+ // In environments where built-in hashing functions are available, we prefer
90+ // those instead. Like Node's crypto module, or Bun.hash. Unfortunately this
91+ // does not include the web standard crypto API because those methods are all
92+ // async. For our purposes, we need it to be sync because the cost of context
93+ // switching is too high to be worth it.
94+ //
95+ // The most popular hashing algorithm that meets these requirements in the JS
96+ // ecosystem is MurmurHash3, and almost all implementations I could find used
97+ // some version of the implementation by Gary Court inlined below.
98+ function createFastHashJS ( key ) {
99+ return murmurhash3_32_gc ( key , 0 ) ;
100+ }
101+ /* eslint-disable prefer-const, no-fallthrough */
102+
103+ /**
104+ * @license
105+ *
106+ * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011)
107+ *
108+ * Copyright (c) 2011 Gary Court
109+ * Permission is hereby granted, free of charge, to any person obtaining a copy
110+ * of this software and associated documentation files (the "Software"), to deal
111+ * in the Software without restriction, including without limitation the rights
112+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
113+ * copies of the Software, and to permit persons to whom the Software is
114+ * furnished to do so, subject to the following conditions:
115+ *
116+ * The above copyright notice and this permission notice shall be included in
117+ * all copies or substantial portions of the Software.
118+ *
119+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
120+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
121+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
122+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
123+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
124+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
125+ * SOFTWARE.
126+ */
127+
128+ function murmurhash3_32_gc ( key , seed ) {
129+ var remainder , bytes , h1 , h1b , c1 , c2 , k1 , i ;
130+ remainder = key . length & 3 ; // key.length % 4
131+
132+ bytes = key . length - remainder ;
133+ h1 = seed ;
134+ c1 = 0xcc9e2d51 ;
135+ c2 = 0x1b873593 ;
136+ i = 0 ;
137+
138+ while ( i < bytes ) {
139+ k1 =
140+ ( key . charCodeAt ( i ) & 0xff ) |
141+ ( ( key . charCodeAt ( ++ i ) & 0xff ) << 8 ) |
142+ ( ( key . charCodeAt ( ++ i ) & 0xff ) << 16 ) |
143+ ( ( key . charCodeAt ( ++ i ) & 0xff ) << 24 ) ;
144+ ++ i ;
145+ k1 =
146+ ( ( k1 & 0xffff ) * c1 + ( ( ( ( k1 >>> 16 ) * c1 ) & 0xffff ) << 16 ) ) & 0xffffffff ;
147+ k1 = ( k1 << 15 ) | ( k1 >>> 17 ) ;
148+ k1 =
149+ ( ( k1 & 0xffff ) * c2 + ( ( ( ( k1 >>> 16 ) * c2 ) & 0xffff ) << 16 ) ) & 0xffffffff ;
150+ h1 ^= k1 ;
151+ h1 = ( h1 << 13 ) | ( h1 >>> 19 ) ;
152+ h1b =
153+ ( ( h1 & 0xffff ) * 5 + ( ( ( ( h1 >>> 16 ) * 5 ) & 0xffff ) << 16 ) ) & 0xffffffff ;
154+ h1 = ( h1b & 0xffff ) + 0x6b64 + ( ( ( ( h1b >>> 16 ) + 0xe654 ) & 0xffff ) << 16 ) ;
155+ }
156+
157+ k1 = 0 ;
158+
159+ switch ( remainder ) {
160+ case 3 :
161+ k1 ^= ( key . charCodeAt ( i + 2 ) & 0xff ) << 16 ;
162+
163+ case 2 :
164+ k1 ^= ( key . charCodeAt ( i + 1 ) & 0xff ) << 8 ;
165+
166+ case 1 :
167+ k1 ^= key . charCodeAt ( i ) & 0xff ;
168+ k1 =
169+ ( ( k1 & 0xffff ) * c1 + ( ( ( ( k1 >>> 16 ) * c1 ) & 0xffff ) << 16 ) ) &
170+ 0xffffffff ;
171+ k1 = ( k1 << 15 ) | ( k1 >>> 17 ) ;
172+ k1 =
173+ ( ( k1 & 0xffff ) * c2 + ( ( ( ( k1 >>> 16 ) * c2 ) & 0xffff ) << 16 ) ) &
174+ 0xffffffff ;
175+ h1 ^= k1 ;
176+ }
177+
178+ h1 ^= key . length ;
179+ h1 ^= h1 >>> 16 ;
180+ h1 =
181+ ( ( h1 & 0xffff ) * 0x85ebca6b +
182+ ( ( ( ( h1 >>> 16 ) * 0x85ebca6b ) & 0xffff ) << 16 ) ) &
183+ 0xffffffff ;
184+ h1 ^= h1 >>> 13 ;
185+ h1 =
186+ ( ( h1 & 0xffff ) * 0xc2b2ae35 +
187+ ( ( ( ( h1 >>> 16 ) * 0xc2b2ae35 ) & 0xffff ) << 16 ) ) &
188+ 0xffffffff ;
189+ h1 ^= h1 >>> 16 ;
190+ return h1 >>> 0 ;
191+ }
192+
84193function scheduleWork ( callback ) {
85194 callback ( ) ;
86195}
@@ -108,9 +217,6 @@ function closeWithError(destination, error) {
108217 // $FlowFixMe[incompatible-call]: This is an Error object or the destination accepts other types.
109218 destination . destroy ( error ) ;
110219}
111- function createFastHash ( input ) {
112- return input ;
113- }
114220
115221var assign = Object . assign ;
116222
@@ -9488,7 +9594,7 @@ function createPostbackFormStateKey(permalink, componentKeyPath, hookIndex) {
94889594 // and it's more important that it's fast than that it's completely
94899595 // collision-free.
94909596
9491- var keyPathHash = createFastHash ( JSON . stringify ( keyPath ) ) ;
9597+ var keyPathHash = createFastHashJS ( JSON . stringify ( keyPath ) ) ;
94929598 return "k" + keyPathHash ;
94939599 }
94949600}
0 commit comments