Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/GfxDriverInfo.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#ifndef __mozilla_widget_GfxDriverInfo_h__
7
#define __mozilla_widget_GfxDriverInfo_h__
8
9
#include "nsString.h"
10
11
// Macros for adding a blocklist item to the static list.
12
#define APPEND_TO_DRIVER_BLOCKLIST(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion) \
13
    sDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion))
14
#define APPEND_TO_DRIVER_BLOCKLIST2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId) \
15
    sDriverInfo->AppendElement(GfxDriverInfo(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId))
16
17
#define APPEND_TO_DRIVER_BLOCKLIST_RANGE(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, ruleId, suggestedVersion) \
18
    do { \
19
      MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
20
                 driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
21
                 driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
22
      GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion); \
23
      info.mDriverVersionMax = driverVersionMax; \
24
      sDriverInfo->AppendElement(info); \
25
    } while (false)
26
27
#define APPEND_TO_DRIVER_BLOCKLIST_RANGE_GPU2(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, driverVersionMax, ruleId, suggestedVersion) \
28
    do { \
29
      MOZ_ASSERT(driverComparator == DRIVER_BETWEEN_EXCLUSIVE || \
30
                 driverComparator == DRIVER_BETWEEN_INCLUSIVE || \
31
                 driverComparator == DRIVER_BETWEEN_INCLUSIVE_START); \
32
      GfxDriverInfo info(os, vendor, devices, feature, featureStatus, driverComparator, driverVersion, ruleId, suggestedVersion, false, true); \
33
      info.mDriverVersionMax = driverVersionMax; \
34
      sDriverInfo->AppendElement(info); \
35
    } while (false)
36
37
38
namespace mozilla {
39
namespace widget {
40
41
enum class OperatingSystem {
42
  Unknown,
43
  Windows,
44
  WindowsXP,
45
  WindowsServer2003,
46
  WindowsVista,
47
  Windows7,
48
  Windows8,
49
  Windows8_1,
50
  Windows10,
51
  Linux,
52
  OSX,
53
  OSX10_5,
54
  OSX10_6,
55
  OSX10_7,
56
  OSX10_8,
57
  OSX10_9,
58
  OSX10_10,
59
  OSX10_11,
60
  OSX10_12,
61
  OSX10_13,
62
  Android,
63
  Ios
64
};
65
66
enum VersionComparisonOp {
67
  DRIVER_LESS_THAN,             // driver <  version
68
  DRIVER_BUILD_ID_LESS_THAN,    // driver build id <  version
69
  DRIVER_LESS_THAN_OR_EQUAL,    // driver <= version
70
  DRIVER_BUILD_ID_LESS_THAN_OR_EQUAL, // driver build id <= version
71
  DRIVER_GREATER_THAN,          // driver >  version
72
  DRIVER_GREATER_THAN_OR_EQUAL, // driver >= version
73
  DRIVER_EQUAL,                 // driver == version
74
  DRIVER_NOT_EQUAL,             // driver != version
75
  DRIVER_BETWEEN_EXCLUSIVE,     // driver > version && driver < versionMax
76
  DRIVER_BETWEEN_INCLUSIVE,     // driver >= version && driver <= versionMax
77
  DRIVER_BETWEEN_INCLUSIVE_START, // driver >= version && driver < versionMax
78
  DRIVER_COMPARISON_IGNORED
79
};
80
81
enum DeviceFamily {
82
  IntelGMA500,
83
  IntelGMA900,
84
  IntelGMA950,
85
  IntelGMA3150,
86
  IntelGMAX3000,
87
  IntelGMAX4500HD,
88
  IntelHDGraphicsToSandyBridge,
89
  IntelHDGraphicsToHaswell,
90
  IntelHD3000,
91
  IntelMobileHDGraphics,
92
  NvidiaBlockD3D9Layers,
93
  RadeonX1000,
94
  Geforce7300GT,
95
  Nvidia310M,
96
  Nvidia8800GTS,
97
  Bug1137716,
98
  Bug1116812,
99
  Bug1155608,
100
  Bug1207665,
101
  Bug1447141,
102
  DeviceFamilyMax
103
};
104
105
enum DeviceVendor {
106
  VendorAll, // There is an assumption that this is the first enum
107
  VendorIntel,
108
  VendorNVIDIA,
109
  VendorAMD,
110
  VendorATI,
111
  VendorMicrosoft,
112
  VendorParallels,
113
  VendorQualcomm,
114
  DeviceVendorMax
115
};
116
117
/* Array of devices to match, or an empty array for all devices */
118
typedef nsTArray<nsString> GfxDeviceFamily;
119
120
struct GfxDriverInfo
121
{
122
  // If |ownDevices| is true, you are transferring ownership of the devices
123
  // array, and it will be deleted when this GfxDriverInfo is destroyed.
124
  GfxDriverInfo(OperatingSystem os, nsAString& vendor, GfxDeviceFamily* devices,
125
                int32_t feature, int32_t featureStatus, VersionComparisonOp op,
126
                uint64_t driverVersion, const char *ruleId,
127
                const char *suggestedVersion = nullptr,
128
                bool ownDevices = false, bool gpu2 = false);
129
130
  GfxDriverInfo();
131
  GfxDriverInfo(const GfxDriverInfo&);
132
  ~GfxDriverInfo();
133
134
  OperatingSystem mOperatingSystem;
135
  uint32_t mOperatingSystemVersion;
136
137
  nsString mAdapterVendor;
138
139
  static GfxDeviceFamily* const allDevices;
140
  GfxDeviceFamily* mDevices;
141
142
  // Whether the mDevices array should be deleted when this structure is
143
  // deallocated. False by default.
144
  bool mDeleteDevices;
145
146
  /* A feature from nsIGfxInfo, or all features */
147
  int32_t mFeature;
148
  static int32_t allFeatures;
149
150
  /* A feature status from nsIGfxInfo */
151
  int32_t mFeatureStatus;
152
153
  VersionComparisonOp mComparisonOp;
154
155
  /* versions are assumed to be A.B.C.D packed as 0xAAAABBBBCCCCDDDD */
156
  uint64_t mDriverVersion;
157
  uint64_t mDriverVersionMax;
158
  static uint64_t allDriverVersions;
159
160
  const char *mSuggestedVersion;
161
  nsCString mRuleId;
162
163
  static const GfxDeviceFamily* GetDeviceFamily(DeviceFamily id);
164
  static GfxDeviceFamily* sDeviceFamilies[DeviceFamilyMax];
165
166
  static const nsAString& GetDeviceVendor(DeviceVendor id);
167
  static nsAString* sDeviceVendors[DeviceVendorMax];
168
169
  nsString mModel, mHardware, mProduct, mManufacturer;
170
171
  bool mGpu2;
172
};
173
174
#define GFX_DRIVER_VERSION(a,b,c,d) \
175
  ((uint64_t(a)<<48) | (uint64_t(b)<<32) | (uint64_t(c)<<16) | uint64_t(d))
176
177
inline uint64_t
178
V(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
179
{
180
  // We make sure every driver number is padded by 0s, this will allow us the
181
  // easiest 'compare as if decimals' approach. See ParseDriverVersion for a
182
  // more extensive explanation of this approach.
183
  while (b > 0 && b < 1000) {
184
    b *= 10;
185
  }
186
  while (c > 0 && c < 1000) {
187
    c *= 10;
188
  }
189
  while (d > 0 && d < 1000) {
190
    d *= 10;
191
  }
192
  return GFX_DRIVER_VERSION(a, b, c, d);
193
}
194
195
// All destination string storage needs to have at least 5 bytes available.
196
inline bool SplitDriverVersion(const char *aSource, char *aAStr, char *aBStr, char *aCStr, char *aDStr)
197
0
{
198
0
  // sscanf doesn't do what we want here to we parse this manually.
199
0
  int len = strlen(aSource);
200
0
201
0
  // This "4" is hardcoded in a few places, including once as a 3.
202
0
  char *dest[4] = { aAStr, aBStr, aCStr, aDStr };
203
0
  unsigned destIdx = 0;
204
0
  unsigned destPos = 0;
205
0
206
0
  for (int i = 0; i < len; i++) {
207
0
    if (destIdx >= 4) {
208
0
      // Invalid format found. Ensure we don't access dest beyond bounds.
209
0
      return false;
210
0
    }
211
0
212
0
    if (aSource[i] == '.') {
213
0
      MOZ_ASSERT (destIdx < 4 && destPos <= 4);
214
0
      dest[destIdx++][destPos] = 0;
215
0
      destPos = 0;
216
0
      continue;
217
0
    }
218
0
219
0
    if (destPos > 3) {
220
0
      // Ignore more than 4 chars. Ensure we never access dest[destIdx]
221
0
      // beyond its bounds.
222
0
      continue;
223
0
    }
224
0
225
0
    MOZ_ASSERT (destIdx < 4 && destPos < 4);
226
0
    dest[destIdx][destPos++] = aSource[i];
227
0
  }
228
0
229
0
  // Take care of the trailing period
230
0
  if (destIdx >= 4) {
231
0
    return false;
232
0
  }
233
0
234
0
  // Add last terminator.
235
0
  MOZ_ASSERT (destIdx < 4 && destPos <= 4);
236
0
  dest[destIdx][destPos] = 0;
237
0
238
0
  if (destIdx != 3) {
239
0
    return false;
240
0
  }
241
0
  return true;
242
0
}
243
244
// This allows us to pad driver version 'substrings' with 0s, this
245
// effectively allows us to treat the version numbers as 'decimals'. This is
246
// a little strange but this method seems to do the right thing for all
247
// different vendor's driver strings. i.e. .98 will become 9800, which is
248
// larger than .978 which would become 9780.
249
inline void PadDriverDecimal(char *aString)
250
{
251
  for (int i = 0; i < 4; i++) {
252
    if (!aString[i]) {
253
      for (int c = i; c < 4; c++) {
254
        aString[c] = '0';
255
      }
256
      break;
257
    }
258
  }
259
  aString[4] = 0;
260
}
261
262
inline bool
263
ParseDriverVersion(const nsAString& aVersion, uint64_t *aNumericVersion)
264
{
265
  *aNumericVersion = 0;
266
267
#if defined(XP_WIN)
268
  int a, b, c, d;
269
  char aStr[8], bStr[8], cStr[8], dStr[8];
270
  /* honestly, why do I even bother */
271
  if (!SplitDriverVersion(NS_LossyConvertUTF16toASCII(aVersion).get(), aStr, bStr, cStr, dStr))
272
    return false;
273
274
  PadDriverDecimal(bStr);
275
  PadDriverDecimal(cStr);
276
  PadDriverDecimal(dStr);
277
278
  a = atoi(aStr);
279
  b = atoi(bStr);
280
  c = atoi(cStr);
281
  d = atoi(dStr);
282
283
  if (a < 0 || a > 0xffff) return false;
284
  if (b < 0 || b > 0xffff) return false;
285
  if (c < 0 || c > 0xffff) return false;
286
  if (d < 0 || d > 0xffff) return false;
287
288
  *aNumericVersion = GFX_DRIVER_VERSION(a, b, c, d);
289
  MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
290
  return true;
291
#elif defined(ANDROID)
292
  // Can't use aVersion.ToInteger() because that's not compiled into our code
293
  // unless we have XPCOM_GLUE_AVOID_NSPR disabled.
294
  *aNumericVersion = atoi(NS_LossyConvertUTF16toASCII(aVersion).get());
295
  MOZ_ASSERT(*aNumericVersion != GfxDriverInfo::allDriverVersions);
296
  return true;
297
#else
298
  return false;
299
#endif
300
}
301
302
} // namespace widget
303
} // namespace mozilla
304
305
#endif /*__mozilla_widget_GfxDriverInfo_h__ */