Skip to content
Snippets Groups Projects
Commit 980802e4 authored by Oz Linden's avatar Oz Linden
Browse files

STORM-1552: detect, ignore, and delete invalid feature and gpu table files

parent 6e113858
No related branches found
No related tags found
No related merge requests found
//GPU_TABLE - that token on line 1 tags this as a gpu table file
// //
// Categorizes graphics chips into various classes by name // Categorizes graphics chips into various classes by name
// //
......
...@@ -261,7 +261,7 @@ BOOL LLFeatureManager::maskFeatures(const std::string& name) ...@@ -261,7 +261,7 @@ BOOL LLFeatureManager::maskFeatures(const std::string& name)
return maskList(*maskp); return maskList(*maskp);
} }
BOOL LLFeatureManager::loadFeatureTables() bool LLFeatureManager::loadFeatureTables()
{ {
// *TODO - if I or anyone else adds something else to the skipped list // *TODO - if I or anyone else adds something else to the skipped list
// make this data driven. Put it in the feature table and parse it // make this data driven. Put it in the feature table and parse it
...@@ -302,28 +302,36 @@ BOOL LLFeatureManager::loadFeatureTables() ...@@ -302,28 +302,36 @@ BOOL LLFeatureManager::loadFeatureTables()
// use HTTP table if it exists // use HTTP table if it exists
std::string path; std::string path;
bool parse_ok = false;
if (gDirUtilp->fileExists(http_path)) if (gDirUtilp->fileExists(http_path))
{ {
path = http_path; parse_ok = parseFeatureTable(http_path);
} if (!parse_ok)
else
{ {
path = app_path; // the HTTP table failed to parse, so delete it
LLFile::remove(http_path);
LL_WARNS("RenderInit") << "Removed invalid feature table '" << http_path << "'" << LL_ENDL;
}
} }
if (!parse_ok)
{
parse_ok = parseFeatureTable(app_path);
}
return parseFeatureTable(path); return parse_ok;
} }
BOOL LLFeatureManager::parseFeatureTable(std::string filename) bool LLFeatureManager::parseFeatureTable(std::string filename)
{ {
llinfos << "Looking for feature table in " << filename << llendl; LL_INFOS("RenderInit") << "Attempting to parse feature table from " << filename << LL_ENDL;
llifstream file; llifstream file;
std::string name; std::string name;
U32 version; U32 version;
cleanupFeatureTables(); // in case an earlier attempt left partial results
file.open(filename); /*Flawfinder: ignore*/ file.open(filename); /*Flawfinder: ignore*/
if (!file) if (!file)
...@@ -338,13 +346,14 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename) ...@@ -338,13 +346,14 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)
if (name != "version") if (name != "version")
{ {
LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL; LL_WARNS("RenderInit") << filename << " does not appear to be a valid feature table!" << LL_ENDL;
return FALSE; return false;
} }
mTableVersion = version; mTableVersion = version;
LLFeatureList *flp = NULL; LLFeatureList *flp = NULL;
while (file >> name) bool parse_ok = true;
while (file >> name && parse_ok)
{ {
char buffer[MAX_STRING]; /*Flawfinder: ignore*/ char buffer[MAX_STRING]; /*Flawfinder: ignore*/
...@@ -357,39 +366,58 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename) ...@@ -357,39 +366,58 @@ BOOL LLFeatureManager::parseFeatureTable(std::string filename)
if (name == "list") if (name == "list")
{ {
LL_DEBUGS("RenderInit") << "Before new list" << std::endl;
if (flp) if (flp)
{ {
//flp->dump(); flp->dump();
} }
// It's a new mask, create it. else
file >> name;
if (mMaskList.count(name))
{ {
LL_ERRS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL; LL_CONT << "No current list";
} }
LL_CONT << LL_ENDL;
// It's a new mask, create it.
file >> name;
if (!mMaskList.count(name))
{
flp = new LLFeatureList(name); flp = new LLFeatureList(name);
mMaskList[name] = flp; mMaskList[name] = flp;
} }
else else
{
LL_WARNS("RenderInit") << "Overriding mask " << name << ", this is invalid!" << LL_ENDL;
parse_ok = false;
}
}
else
{ {
if (!flp) if (!flp)
{ {
LL_ERRS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
return FALSE;
}
S32 available; S32 available;
F32 recommended; F32 recommended;
file >> available >> recommended; file >> available >> recommended;
flp->addFeature(name, available, recommended); flp->addFeature(name, available, recommended);
} }
else
{
LL_WARNS("RenderInit") << "Specified parameter before <list> keyword!" << LL_ENDL;
parse_ok = false;
}
}
} }
file.close(); file.close();
return TRUE; if (!parse_ok)
{
LL_WARNS("RenderInit") << "Discarding feature table data from " << filename << LL_ENDL;
cleanupFeatureTables();
}
return parse_ok;
} }
void LLFeatureManager::loadGPUClass() bool LLFeatureManager::loadGPUClass()
{ {
// defaults // defaults
mGPUClass = GPU_CLASS_UNKNOWN; mGPUClass = GPU_CLASS_UNKNOWN;
...@@ -407,29 +435,49 @@ void LLFeatureManager::loadGPUClass() ...@@ -407,29 +435,49 @@ void LLFeatureManager::loadGPUClass()
// use HTTP table if it exists // use HTTP table if it exists
std::string path; std::string path;
bool parse_ok = false;
if (gDirUtilp->fileExists(http_path)) if (gDirUtilp->fileExists(http_path))
{ {
path = http_path; parse_ok = parseGPUTable(http_path);
if (!parse_ok)
{
// the HTTP table failed to parse, so delete it
LLFile::remove(http_path);
LL_WARNS("RenderInit") << "Removed invalid gpu table '" << http_path << "'" << LL_ENDL;
} }
else }
if (!parse_ok)
{ {
path = app_path; parse_ok = parseGPUTable(app_path);
} }
parseGPUTable(path); return parse_ok; // indicates that the file parsed correctly, not that the gpu was recognized
} }
void LLFeatureManager::parseGPUTable(std::string filename) bool LLFeatureManager::parseGPUTable(std::string filename)
{ {
llifstream file; llifstream file;
LL_INFOS("RenderInit") << "Attempting to parse GPU table from " << filename << LL_ENDL;
file.open(filename); file.open(filename);
if (!file) if (file)
{
const char recognizer[] = "//GPU_TABLE";
char first_line[MAX_STRING];
file.getline(first_line, MAX_STRING);
if (0 != strncmp(first_line, recognizer, strlen(recognizer)))
{
LL_WARNS("RenderInit") << "Invalid GPU table: " << filename << "!" << LL_ENDL;
return false;
}
}
else
{ {
LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL; LL_WARNS("RenderInit") << "Unable to open GPU table: " << filename << "!" << LL_ENDL;
return; return false;
} }
std::string rawRenderer = gGLManager.getRawGLString(); std::string rawRenderer = gGLManager.getRawGLString();
...@@ -556,6 +604,7 @@ void LLFeatureManager::parseGPUTable(std::string filename) ...@@ -556,6 +604,7 @@ void LLFeatureManager::parseGPUTable(std::string filename)
#if LL_DARWIN // never go over "Mid" settings by default on OS X #if LL_DARWIN // never go over "Mid" settings by default on OS X
mGPUClass = llmin(mGPUClass, GPU_CLASS_2); mGPUClass = llmin(mGPUClass, GPU_CLASS_2);
#endif #endif
return true;
} }
// responder saves table into file // responder saves table into file
......
...@@ -75,7 +75,7 @@ class LLFeatureList ...@@ -75,7 +75,7 @@ class LLFeatureList
void setFeatureAvailable(const std::string& name, const BOOL available); void setFeatureAvailable(const std::string& name, const BOOL available);
void setRecommendedLevel(const std::string& name, const F32 level); void setRecommendedLevel(const std::string& name, const F32 level);
BOOL loadFeatureList(LLFILE *fp); bool loadFeatureList(LLFILE *fp);
BOOL maskList(LLFeatureList &mask); BOOL maskList(LLFeatureList &mask);
...@@ -114,7 +114,7 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag ...@@ -114,7 +114,7 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag
void maskCurrentList(const std::string& name); // Mask the current feature list with the named list void maskCurrentList(const std::string& name); // Mask the current feature list with the named list
BOOL loadFeatureTables(); bool loadFeatureTables();
EGPUClass getGPUClass() { return mGPUClass; } EGPUClass getGPUClass() { return mGPUClass; }
std::string& getGPUString() { return mGPUString; } std::string& getGPUString() { return mGPUString; }
...@@ -157,9 +157,14 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag ...@@ -157,9 +157,14 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag
void fetchHTTPTables(); void fetchHTTPTables();
protected: protected:
void loadGPUClass(); bool loadGPUClass();
BOOL parseFeatureTable(std::string filename);
void parseGPUTable(std::string filename); bool parseFeatureTable(std::string filename);
///< @returns TRUE is file parsed correctly, FALSE if not
bool parseGPUTable(std::string filename);
///< @returns true if file parsed correctly, false if not - does not reflect whether or not the gpu was recognized
void initBaseMask(); void initBaseMask();
......
...@@ -73,6 +73,10 @@ die "Must specify a --gpu-table <gpu_table.txt> value" ...@@ -73,6 +73,10 @@ die "Must specify a --gpu-table <gpu_table.txt> value"
open(GPUS, "<$GpuTable") open(GPUS, "<$GpuTable")
|| die "Failed to open gpu table '$GpuTable':\n\t$!\n"; || die "Failed to open gpu table '$GpuTable':\n\t$!\n";
my $FirstLine = <GPUS>;
die "First line of gpu table does not begin with '//GPU_TABLE'"
unless $FirstLine =~ m|^//GPU_TABLE|;
# Parse the GPU table into these tables, indexed by the name # Parse the GPU table into these tables, indexed by the name
my %NameLine; # name -> line number on which a given name was found (catches duplicate names) my %NameLine; # name -> line number on which a given name was found (catches duplicate names)
my %RecognizerLine; # name -> line number on which a given name was found (catches duplicate names) my %RecognizerLine; # name -> line number on which a given name was found (catches duplicate names)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment