int php_tag_find(char *tag, size_t len, const char *set);
+#ifdef PHP_WIN32
+# define SET_ALIGNED(alignment, decl) __declspec(align(alignment)) decl
+#elif HAVE_ATTRIBUTE_ALIGNED
+# define SET_ALIGNED(alignment, decl) decl __attribute__ ((__aligned__ (alignment)))
+#else
+# define SET_ALIGNED(alignment, decl) decl
+#endif
+
/* this is read-only, so it's ok */
-static char hexconvtab[] = "0123456789abcdef";
+SET_ALIGNED(16, static char hexconvtab[]) = "0123456789abcdef";
/* localeconv mutex */
#ifdef ZTS
for (i = j = 0; i < target_length; i++) {
unsigned char c = old[j++];
+ unsigned char l = c & ~0x20;
+ int is_letter = ((unsigned int) ((l - 'A') ^ (l - 'F' - 1))) >> (8 * sizeof(unsigned int) - 1);
unsigned char d;
- if (c >= '0' && c <= '9') {
- d = (c - '0') << 4;
- } else if (c >= 'a' && c <= 'f') {
- d = (c - 'a' + 10) << 4;
- } else if (c >= 'A' && c <= 'F') {
- d = (c - 'A' + 10) << 4;
+ /* basically (c >= '0' && c <= '9') || (l >= 'A' && l <= 'F') */
+ if (EXPECTED((((c ^ '0') - 10) >> (8 * sizeof(unsigned int) - 1)) | is_letter)) {
+ d = (l - 0x10 - 0x27 * is_letter) << 4;
} else {
zend_string_free(str);
return NULL;
}
c = old[j++];
- if (c >= '0' && c <= '9') {
- d |= c - '0';
- } else if (c >= 'a' && c <= 'f') {
- d |= c - 'a' + 10;
- } else if (c >= 'A' && c <= 'F') {
- d |= c - 'A' + 10;
+ l = c & ~0x20;
+ is_letter = ((unsigned int) ((l - 'A') ^ (l - 'F' - 1))) >> (8 * sizeof(unsigned int) - 1);
+ if (EXPECTED((((c ^ '0') - 10) >> (8 * sizeof(unsigned int) - 1)) | is_letter)) {
+ d |= l - 0x10 - 0x27 * is_letter;
} else {
zend_string_free(str);
return NULL;