Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Bug 791742 - Consider driver version substrings in decimals. r=joedre…

…w, a=lsblakk
  • Loading branch information...
commit 24eb718c50e9bf7fe9c80d25f08ee571eb0bd179 1 parent d484af5
authored September 17, 2012
3  widget/windows/GfxInfo.cpp
@@ -33,9 +33,6 @@ NS_IMPL_ISUPPORTS_INHERITED1(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
33 33
 
34 34
 static const uint32_t allWindowsVersions = 0xffffffff;
35 35
 
36  
-#define V(a,b,c,d) GFX_DRIVER_VERSION(a,b,c,d)
37  
-
38  
-
39 36
 GfxInfo::GfxInfo()
40 37
  :  mWindowsVersion(0),
41 38
     mHasDualGPU(false),
91  widget/xpwidgets/GfxDriverInfo.h
@@ -9,8 +9,6 @@
9 9
 #ifndef __mozilla_widget_GfxDriverInfo_h__
10 10
 #define __mozilla_widget_GfxDriverInfo_h__
11 11
 
12  
-#define V(a,b,c,d) GFX_DRIVER_VERSION(a,b,c,d)
13  
-
14 12
 // Macros for adding a blocklist item to the static list.
15 13
 #define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion) \
16 14
     mDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, suggestedVersion))
@@ -124,15 +122,100 @@ struct GfxDriverInfo
124 122
 #define GFX_DRIVER_VERSION(a,b,c,d) \
125 123
   ((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d))
126 124
 
  125
+static uint64_t
  126
+V(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
  127
+{
  128
+  // We make sure every driver number is padded by 0s, this will allow us the
  129
+  // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
  130
+  // more extensive explanation of this approach.
  131
+  while (b > 0 && b < 1000) {
  132
+    b *= 10;
  133
+  }
  134
+  while (c > 0 && c < 1000) {
  135
+    c *= 10;
  136
+  }
  137
+  while (d > 0 && d < 1000) {
  138
+    d *= 10;
  139
+  }
  140
+  return GFX_DRIVER_VERSION(a, b, c, d);
  141
+}
  142
+
  143
+// All destination string storage needs to have at least 5 bytes available.
  144
+static bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr, char *aCStr, char *aDStr)
  145
+{
  146
+  // sscanf doesn't do what we want here to we parse this manually.
  147
+  int len = strlen(aSource);
  148
+  char *dest[4] = { aAStr, aBStr, aCStr, aDStr };
  149
+  int destIdx = 0;
  150
+  int destPos = 0;
  151
+
  152
+  for (int i = 0; i < len; i++) {
  153
+    if (destIdx > ArrayLength(dest)) {
  154
+      // Invalid format found. Ensure we don't access dest beyond bounds.
  155
+      return false;
  156
+    }
  157
+
  158
+    if (aSource[i] == '.') {
  159
+      dest[destIdx++][destPos] = 0;
  160
+      destPos = 0;
  161
+      continue;
  162
+    }
  163
+
  164
+    if (destPos > 3) {
  165
+      // Ignore more than 4 chars. Ensure we never access dest[destIdx]
  166
+      // beyond its bounds.
  167
+      continue;
  168
+    }
  169
+
  170
+    dest[destIdx][destPos++] = aSource[i];
  171
+  }
  172
+
  173
+  // Add last terminator.
  174
+  dest[destIdx][destPos] = 0;
  175
+
  176
+  if (destIdx != ArrayLength(dest) - 1) {
  177
+    return false;
  178
+  }
  179
+  return true;
  180
+}
  181
+
  182
+// This allows us to pad driver versiopn 'substrings' with 0s, this
  183
+// effectively allows us to treat the version numbers as 'decimals'. This is
  184
+// a little strange but this method seems to do the right thing for all
  185
+// different vendor's driver strings. i.e. .98 will become 9800, which is
  186
+// larger than .978 which would become 9780.
  187
+static void PadDriverDecimal(char *aString)
  188
+{
  189
+  for (int i = 0; i < 4; i++) {
  190
+    if (!aString[i]) {
  191
+      for (int c = i; c < 4; c++) {
  192
+        aString[c] = '0';
  193
+      }
  194
+      break;
  195
+    }
  196
+  }
  197
+  aString[4] = 0;
  198
+}
  199
+
127 200
 inline bool
128 201
 ParseDriverVersion(nsAString& aVersion, uint64_t *aNumericVersion)
129 202
 {
130 203
 #if defined(XP_WIN)
131 204
   int a, b, c, d;
  205
+  char aStr[8], bStr[8], cStr[8], dStr[8];
132 206
   /* honestly, why do I even bother */
133  
-  if (sscanf(NS_LossyConvertUTF16toASCII(aVersion).get(),
134  
-             "%d.%d.%d.%d", &a, &b, &c, &d) != 4)
  207
+  if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr, bStr, cStr, dStr))
135 208
     return false;
  209
+
  210
+  PadDriverDecimal(bStr);
  211
+  PadDriverDecimal(cStr);
  212
+  PadDriverDecimal(dStr);
  213
+
  214
+  a = atoi(aStr);
  215
+  b = atoi(bStr);
  216
+  c = atoi(cStr);
  217
+  d = atoi(dStr);
  218
+
136 219
   if (a < 0 || a > 0xffff) return false;
137 220
   if (b < 0 || b > 0xffff) return false;
138 221
   if (c < 0 || c > 0xffff) return false;

0 notes on commit 24eb718

Please sign in to comment.
Something went wrong with that request. Please try again.