Changeset 165681 in webkit
- Timestamp:
- Mar 15, 2014 8:21:06 AM (10 years ago)
- Location:
- trunk/Source/WTF
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r165677 r165681 1 2014-03-15 David Kilzer <ddkilzer@apple.com> 2 3 Fix undefined behavior in WTF::equal() in StringImpl.h for i386/x86_64 4 <http://webkit.org/b/130283> 5 <rdar://problem/16281477> 6 7 Reviewed by Geoff Garen. 8 9 * wtf/text/StringImpl.h: 10 (WTF::loadUnaligned): Add template method. 11 (WTF::equal): Switch to using loadUnaligned<>(). 12 1 13 2014-03-14 Mark Rowe <mrowe@apple.com> 2 14 -
trunk/Source/WTF/wtf/text/StringImpl.h
r165152 r165681 916 916 WTF_EXPORT_STRING_API bool equal(const StringImpl& a, const StringImpl& b); 917 917 918 template<typename T> 919 inline T loadUnaligned(const char* s) 920 { 921 T tmp; 922 memcpy(&tmp, s, sizeof(T)); 923 return tmp; 924 } 925 918 926 // Do comparisons 8 or 4 bytes-at-a-time on architectures where it's safe. 919 927 #if CPU(X86_64) || CPU(ARM64) 920 ALWAYS_INLINE bool equal(const LChar* a , const LChar* b, unsigned length)928 ALWAYS_INLINE bool equal(const LChar* aLChar, const LChar* bLChar, unsigned length) 921 929 { 922 930 unsigned dwordLength = length >> 3; 923 931 932 const char* a = reinterpret_cast<const char*>(aLChar); 933 const char* b = reinterpret_cast<const char*>(bLChar); 934 924 935 if (dwordLength) { 925 const uint64_t* aDWordCharacters = reinterpret_cast<const uint64_t*>(a);926 const uint64_t* bDWordCharacters = reinterpret_cast<const uint64_t*>(b);927 928 936 for (unsigned i = 0; i != dwordLength; ++i) { 929 if ( *aDWordCharacters++ != *bDWordCharacters++)937 if (loadUnaligned<uint64_t>(a) != loadUnaligned<uint64_t>(b)) 930 938 return false; 939 940 a += sizeof(uint64_t); 941 b += sizeof(uint64_t); 931 942 } 932 933 a = reinterpret_cast<const LChar*>(aDWordCharacters);934 b = reinterpret_cast<const LChar*>(bDWordCharacters);935 943 } 936 944 937 945 if (length & 4) { 938 if ( *reinterpret_cast<const uint32_t*>(a) != *reinterpret_cast<const uint32_t*>(b))946 if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b)) 939 947 return false; 940 948 941 a += 4;942 b += 4;949 a += sizeof(uint32_t); 950 b += sizeof(uint32_t); 943 951 } 944 952 945 953 if (length & 2) { 946 if ( *reinterpret_cast<const uint16_t*>(a) != *reinterpret_cast<const uint16_t*>(b))954 if (loadUnaligned<uint16_t>(a) != loadUnaligned<uint16_t>(b)) 947 955 return false; 948 956 949 a += 2;950 b += 2;951 } 952 953 if (length & 1 && (* a != *b))957 a += sizeof(uint16_t); 958 b += sizeof(uint16_t); 959 } 960 961 if (length & 1 && (*reinterpret_cast<const LChar*>(a) != *reinterpret_cast<const LChar*>(b))) 954 962 return false; 955 963 … … 957 965 } 958 966 959 ALWAYS_INLINE bool equal(const UChar* a , const UChar* b, unsigned length)967 ALWAYS_INLINE bool equal(const UChar* aUChar, const UChar* bUChar, unsigned length) 960 968 { 961 969 unsigned dwordLength = length >> 2; 962 970 971 const char* a = reinterpret_cast<const char*>(aUChar); 972 const char* b = reinterpret_cast<const char*>(bUChar); 973 963 974 if (dwordLength) { 964 const uint64_t* aDWordCharacters = reinterpret_cast<const uint64_t*>(a);965 const uint64_t* bDWordCharacters = reinterpret_cast<const uint64_t*>(b);966 967 975 for (unsigned i = 0; i != dwordLength; ++i) { 968 if ( *aDWordCharacters++ != *bDWordCharacters++)976 if (loadUnaligned<uint64_t>(a) != loadUnaligned<uint64_t>(b)) 969 977 return false; 978 979 a += sizeof(uint64_t); 980 b += sizeof(uint64_t); 970 981 } 971 972 a = reinterpret_cast<const UChar*>(aDWordCharacters);973 b = reinterpret_cast<const UChar*>(bDWordCharacters);974 982 } 975 983 976 984 if (length & 2) { 977 if ( *reinterpret_cast<const uint32_t*>(a) != *reinterpret_cast<const uint32_t*>(b))985 if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b)) 978 986 return false; 979 987 980 a += 2;981 b += 2;982 } 983 984 if (length & 1 && (* a != *b))988 a += sizeof(uint32_t); 989 b += sizeof(uint32_t); 990 } 991 992 if (length & 1 && (*reinterpret_cast<const UChar*>(a) != *reinterpret_cast<const UChar*>(b))) 985 993 return false; 986 994 … … 988 996 } 989 997 #elif CPU(X86) 990 ALWAYS_INLINE bool equal(const LChar* a , const LChar* b, unsigned length)991 { 992 const uint32_t* aCharacters = reinterpret_cast<const uint32_t*>(a);993 const uint32_t* bCharacters = reinterpret_cast<const uint32_t*>(b);998 ALWAYS_INLINE bool equal(const LChar* aLChar, const LChar* bLChar, unsigned length) 999 { 1000 const char* a = reinterpret_cast<const char*>(aLChar); 1001 const char* b = reinterpret_cast<const char*>(bLChar); 994 1002 995 1003 unsigned wordLength = length >> 2; 996 1004 for (unsigned i = 0; i != wordLength; ++i) { 997 if ( *aCharacters++ != *bCharacters++)1005 if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b)) 998 1006 return false; 1007 a += sizeof(uint32_t); 1008 b += sizeof(uint32_t); 999 1009 } 1000 1010 … … 1002 1012 1003 1013 if (length) { 1004 const LChar* aRemainder = reinterpret_cast<const LChar*>(a Characters);1005 const LChar* bRemainder = reinterpret_cast<const LChar*>(b Characters);1006 1014 const LChar* aRemainder = reinterpret_cast<const LChar*>(a); 1015 const LChar* bRemainder = reinterpret_cast<const LChar*>(b); 1016 1007 1017 for (unsigned i = 0; i < length; ++i) { 1008 1018 if (aRemainder[i] != bRemainder[i]) … … 1014 1024 } 1015 1025 1016 ALWAYS_INLINE bool equal(const UChar* a , const UChar* b, unsigned length)1017 { 1018 const uint32_t* aCharacters = reinterpret_cast<const uint32_t*>(a);1019 const uint32_t* bCharacters = reinterpret_cast<const uint32_t*>(b);1020 1026 ALWAYS_INLINE bool equal(const UChar* aUChar, const UChar* bUChar, unsigned length) 1027 { 1028 const char* a = reinterpret_cast<const char*>(aUChar); 1029 const char* b = reinterpret_cast<const char*>(bUChar); 1030 1021 1031 unsigned wordLength = length >> 1; 1022 1032 for (unsigned i = 0; i != wordLength; ++i) { 1023 if ( *aCharacters++ != *bCharacters++)1033 if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b)) 1024 1034 return false; 1025 } 1026 1027 if (length & 1 && *reinterpret_cast<const UChar*>(aCharacters) != *reinterpret_cast<const UChar*>(bCharacters)) 1035 a += sizeof(uint32_t); 1036 b += sizeof(uint32_t); 1037 } 1038 1039 if (length & 1 && *reinterpret_cast<const UChar*>(a) != *reinterpret_cast<const UChar*>(b)) 1028 1040 return false; 1029 1041 1030 1042 return true; 1031 1043 }
Note: See TracChangeset
for help on using the changeset viewer.