		void CWebServer::GetAppCache(WebEmSession & session, const request& req, reply & rep)
		{
			std::string response = "";
			if (g_bDontCacheWWW)
			{
				return;
			}
			std::string sLine;
			std::string filename = szWWWFolder + "/html5.appcache";


			std::string sWebTheme = "default";
			m_sql.GetPreferencesVar("WebTheme", sWebTheme);

			std::map<std::string, int> _ThemeFiles;
			GetDirFilesRecursive(szWWWFolder + "/styles/" + sWebTheme + "/", _ThemeFiles);

			std::map<std::string, int> _FloorplanFiles;
			std::vector<std::vector<std::string> > result;
			result = m_sql.safe_query("SELECT ID FROM Floorplans ORDER BY [Order]");
			if (!result.empty())
			{
				for (const auto & itt : result)
				{
					std::vector<std::string> sd = itt;
					std::string ImageURL = "images/floorplans/plan?idx=" + sd[0];
					_FloorplanFiles[ImageURL] = 1;
				}
			}

			std::ifstream is(filename.c_str());
			if (is)
			{
				while (!is.eof())
				{
					getline(is, sLine);
					if (!sLine.empty())
					{
						if (sLine.find("#BuildHash") != std::string::npos)
						{
							stdreplace(sLine, "#BuildHash", szAppHash);
						}
						else if (sLine.find("#ThemeFiles") != std::string::npos)
						{
							response += "#Theme=" + sWebTheme + '\n';
							for (const auto & itt : _ThemeFiles)
							{
								std::string tfname = itt.first.substr(szWWWFolder.size() + 1);
								stdreplace(tfname, "styles/" + sWebTheme, "acttheme");
								response += tfname + '\n';
							}
							continue;
						}
						else if (sLine.find("#Floorplans") != std::string::npos)
						{
							for (const auto & itt : _FloorplanFiles)
							{
								std::string tfname = itt.first;
								response += tfname + '\n';
							}
							continue;
						}
						else if (sLine.find("#SwitchIcons") != std::string::npos)
						{
							for (const auto & itt : m_custom_light_icons)
							{
								if (itt.idx >= 100)
								{
									std::string IconFile16 = itt.RootFile + ".png";
									std::string IconFile48On = itt.RootFile + "48_On.png";
									std::string IconFile48Off = itt.RootFile + "48_Off.png";

									response += "images/" + CURLEncode::URLEncode(IconFile16) + '\n';
									response += "images/" + CURLEncode::URLEncode(IconFile48On) + '\n';
									response += "images/" + CURLEncode::URLEncode(IconFile48Off) + '\n';
								}
							}
						}
					}
					response += sLine + '\n';
				}
			}
			reply::set_content(&rep, response);
		}

The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.