133
133
134
134
#if defined(LIBXML_XPATH_ENABLED )
135
135
136
- /************************************************************************
137
- * *
138
- * Floating point stuff *
139
- * *
140
- ************************************************************************/
136
+ static void
137
+ xmlXPathNameFunction (xmlXPathParserContextPtr ctxt , int nargs );
138
+
139
+ static const struct {
140
+ const char * name ;
141
+ xmlXPathFunction func ;
142
+ } xmlXPathStandardFunctions [] = {
143
+ { "boolean" , xmlXPathBooleanFunction },
144
+ { "ceiling" , xmlXPathCeilingFunction },
145
+ { "count" , xmlXPathCountFunction },
146
+ { "concat" , xmlXPathConcatFunction },
147
+ { "contains" , xmlXPathContainsFunction },
148
+ { "id" , xmlXPathIdFunction },
149
+ { "false" , xmlXPathFalseFunction },
150
+ { "floor" , xmlXPathFloorFunction },
151
+ { "last" , xmlXPathLastFunction },
152
+ { "lang" , xmlXPathLangFunction },
153
+ { "local-name" , xmlXPathLocalNameFunction },
154
+ { "not" , xmlXPathNotFunction },
155
+ { "name" , xmlXPathNameFunction },
156
+ { "namespace-uri" , xmlXPathNamespaceURIFunction },
157
+ { "normalize-space" , xmlXPathNormalizeFunction },
158
+ { "number" , xmlXPathNumberFunction },
159
+ { "position" , xmlXPathPositionFunction },
160
+ { "round" , xmlXPathRoundFunction },
161
+ { "string" , xmlXPathStringFunction },
162
+ { "string-length" , xmlXPathStringLengthFunction },
163
+ { "starts-with" , xmlXPathStartsWithFunction },
164
+ { "substring" , xmlXPathSubstringFunction },
165
+ { "substring-before" , xmlXPathSubstringBeforeFunction },
166
+ { "substring-after" , xmlXPathSubstringAfterFunction },
167
+ { "sum" , xmlXPathSumFunction },
168
+ { "true" , xmlXPathTrueFunction },
169
+ { "translate" , xmlXPathTranslateFunction }
170
+ };
171
+
172
+ #define NUM_STANDARD_FUNCTIONS \
173
+ (sizeof(xmlXPathStandardFunctions) / sizeof(xmlXPathStandardFunctions[0]))
174
+
175
+ #define SF_HASH_SIZE 64
176
+
177
+ static unsigned char xmlXPathSFHash [SF_HASH_SIZE ];
141
178
142
179
double xmlXPathNAN = 0.0 ;
143
180
double xmlXPathPINF = 0.0 ;
@@ -153,6 +190,18 @@ xmlXPathInit(void) {
153
190
xmlInitParser ();
154
191
}
155
192
193
+ ATTRIBUTE_NO_SANITIZE_INTEGER
194
+ static unsigned
195
+ xmlXPathSFComputeHash (const xmlChar * name ) {
196
+ unsigned hashValue = 5381 ;
197
+ const xmlChar * ptr ;
198
+
199
+ for (ptr = name ; * ptr ; ptr ++ )
200
+ hashValue = hashValue * 33 + * ptr ;
201
+
202
+ return (hashValue );
203
+ }
204
+
156
205
/**
157
206
* xmlInitXPathInternal:
158
207
*
@@ -161,6 +210,8 @@ xmlXPathInit(void) {
161
210
ATTRIBUTE_NO_SANITIZE ("float-divide-by-zero" )
162
211
void
163
212
xmlInitXPathInternal (void ) {
213
+ size_t i ;
214
+
164
215
#if defined(NAN ) && defined(INFINITY )
165
216
xmlXPathNAN = NAN ;
166
217
xmlXPathPINF = INFINITY ;
@@ -172,8 +223,34 @@ xmlInitXPathInternal(void) {
172
223
xmlXPathPINF = 1.0 / zero ;
173
224
xmlXPathNINF = - xmlXPathPINF ;
174
225
#endif
226
+
227
+ /*
228
+ * Initialize hash table for standard functions
229
+ */
230
+
231
+ for (i = 0 ; i < SF_HASH_SIZE ; i ++ )
232
+ xmlXPathSFHash [i ] = UCHAR_MAX ;
233
+
234
+ for (i = 0 ; i < NUM_STANDARD_FUNCTIONS ; i ++ ) {
235
+ const char * name = xmlXPathStandardFunctions [i ].name ;
236
+ int bucketIndex = xmlXPathSFComputeHash (BAD_CAST name ) % SF_HASH_SIZE ;
237
+
238
+ while (xmlXPathSFHash [bucketIndex ] != UCHAR_MAX ) {
239
+ bucketIndex += 1 ;
240
+ if (bucketIndex >= SF_HASH_SIZE )
241
+ bucketIndex = 0 ;
242
+ }
243
+
244
+ xmlXPathSFHash [bucketIndex ] = i ;
245
+ }
175
246
}
176
247
248
+ /************************************************************************
249
+ * *
250
+ * Floating point stuff *
251
+ * *
252
+ ************************************************************************/
253
+
177
254
/**
178
255
* xmlXPathIsNaN:
179
256
* @val: a double value
@@ -3858,18 +3935,6 @@ xmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
3858
3935
*/
3859
3936
xmlXPathFunction
3860
3937
xmlXPathFunctionLookup (xmlXPathContextPtr ctxt , const xmlChar * name ) {
3861
- if (ctxt == NULL )
3862
- return (NULL );
3863
-
3864
- if (ctxt -> funcLookupFunc != NULL ) {
3865
- xmlXPathFunction ret ;
3866
- xmlXPathFuncLookupFunc f ;
3867
-
3868
- f = ctxt -> funcLookupFunc ;
3869
- ret = f (ctxt -> funcLookupData , name , NULL );
3870
- if (ret != NULL )
3871
- return (ret );
3872
- }
3873
3938
return (xmlXPathFunctionLookupNS (ctxt , name , NULL ));
3874
3939
}
3875
3940
@@ -3894,6 +3959,22 @@ xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
3894
3959
if (name == NULL )
3895
3960
return (NULL );
3896
3961
3962
+ if (ns_uri == NULL ) {
3963
+ int bucketIndex = xmlXPathSFComputeHash (name ) % SF_HASH_SIZE ;
3964
+
3965
+ while (xmlXPathSFHash [bucketIndex ] != UCHAR_MAX ) {
3966
+ int funcIndex = xmlXPathSFHash [bucketIndex ];
3967
+
3968
+ if (strcmp (xmlXPathStandardFunctions [funcIndex ].name ,
3969
+ (char * ) name ) == 0 )
3970
+ return (xmlXPathStandardFunctions [funcIndex ].func );
3971
+
3972
+ bucketIndex += 1 ;
3973
+ if (bucketIndex >= SF_HASH_SIZE )
3974
+ bucketIndex = 0 ;
3975
+ }
3976
+ }
3977
+
3897
3978
if (ctxt -> funcLookupFunc != NULL ) {
3898
3979
xmlXPathFuncLookupFunc f ;
3899
3980
@@ -12807,61 +12888,6 @@ xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) {
12807
12888
void
12808
12889
xmlXPathRegisterAllFunctions (xmlXPathContextPtr ctxt )
12809
12890
{
12810
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"boolean" ,
12811
- xmlXPathBooleanFunction );
12812
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"ceiling" ,
12813
- xmlXPathCeilingFunction );
12814
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"count" ,
12815
- xmlXPathCountFunction );
12816
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"concat" ,
12817
- xmlXPathConcatFunction );
12818
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"contains" ,
12819
- xmlXPathContainsFunction );
12820
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"id" ,
12821
- xmlXPathIdFunction );
12822
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"false" ,
12823
- xmlXPathFalseFunction );
12824
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"floor" ,
12825
- xmlXPathFloorFunction );
12826
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"last" ,
12827
- xmlXPathLastFunction );
12828
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"lang" ,
12829
- xmlXPathLangFunction );
12830
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"local-name" ,
12831
- xmlXPathLocalNameFunction );
12832
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"not" ,
12833
- xmlXPathNotFunction );
12834
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"name" ,
12835
- xmlXPathNameFunction );
12836
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"namespace-uri" ,
12837
- xmlXPathNamespaceURIFunction );
12838
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"normalize-space" ,
12839
- xmlXPathNormalizeFunction );
12840
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"number" ,
12841
- xmlXPathNumberFunction );
12842
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"position" ,
12843
- xmlXPathPositionFunction );
12844
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"round" ,
12845
- xmlXPathRoundFunction );
12846
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"string" ,
12847
- xmlXPathStringFunction );
12848
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"string-length" ,
12849
- xmlXPathStringLengthFunction );
12850
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"starts-with" ,
12851
- xmlXPathStartsWithFunction );
12852
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"substring" ,
12853
- xmlXPathSubstringFunction );
12854
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"substring-before" ,
12855
- xmlXPathSubstringBeforeFunction );
12856
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"substring-after" ,
12857
- xmlXPathSubstringAfterFunction );
12858
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"sum" ,
12859
- xmlXPathSumFunction );
12860
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"true" ,
12861
- xmlXPathTrueFunction );
12862
- xmlXPathRegisterFunc (ctxt , (const xmlChar * )"translate" ,
12863
- xmlXPathTranslateFunction );
12864
-
12865
12891
xmlXPathRegisterFuncNS (ctxt , (const xmlChar * )"escape-uri" ,
12866
12892
(const xmlChar * )"http://www.w3.org/2002/08/xquery-functions" ,
12867
12893
xmlXPathEscapeUriFunction );
0 commit comments