| LEFT | RIGHT | 
|   1 #include "IE_version.h" |   1 #include "IE_version.h" | 
|   2 #include "Registry.h" |   2 #include "Registry.h" | 
 |   3 #include <cstdlib> | 
|   3  |   4  | 
|   4 using namespace AdblockPlus; |   5 using namespace AdblockPlus; | 
|   5  |   6  | 
|   6 /** |   7 /** | 
|   7  * Internal implementation of the IE version string. |   8  * Internal implementation of the IE version string. | 
|   8  * |   9  * | 
|   9  * This version throws exceptions for its errors, relying on its caller to handl
    e them. |  10  * This version throws exceptions for its errors, relying on its caller to handl
    e them. | 
|  10  * |  11  * | 
|  11  * Quoting http://support.microsoft.com/kb/969393: |  12  * Quoting http://support.microsoft.com/kb/969393: | 
|  12  *   "Note The version string value for Internet Explorer 10 is 9.10.9200.16384,
     and the svcVersion string value is 10.0.9200.16384." |  13  *   "Note The version string value for Internet Explorer 10 is 9.10.9200.16384,
     and the svcVersion string value is 10.0.9200.16384." | 
|  13  * [EH 2014-06-20] My current version of IE 11 is reporting these values: |  14  * [EH 2014-06-20] My current version of IE 11 is reporting these values: | 
|  14  *   Version 9.11.9600.17041 |  15  *   Version 9.11.9600.17041 | 
|  15  *   svcVersion 11.0.9600.17041 |  16  *   svcVersion 11.0.9600.17041 | 
|  16  * |  17  * | 
|  17  * Warning: IE version 12 and later might not behave the same, so this function 
    should be reviewed with each new release. |  18  * Warning: IE version 12 and later might not behave the same, so this function 
    should be reviewed with each new release. | 
 |  19  * | 
 |  20  * \par postcondition | 
 |  21  *   Return value matches regex `^[0-9]{1,2}\.$`; this is a sanity check on the 
    format. | 
|  18  */ |  22  */ | 
|  19 std::wstring IE_version_string() |  23 std::wstring IeVersionString() | 
|  20 { |  24 { | 
|  21   Registry_Key IE_key(Registry_Key::Predefined::HKLM, L"Software\\Microsoft\\Int
    ernet Explorer"); |  25   RegistryKey ieKey(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Internet Explorer
    "); | 
|  22   std::wstring version(IE_key.value_wstring(L"Version")); |  26   std::wstring version(ieKey.value_wstring(L"Version")); | 
|  23   /* |  27   /* | 
|  24     * We're expecting a version string that matches the regex "^[1-9]\.". |  28    * We're expecting a version string that matches the regex "^[1-9]\.". | 
|  25     * Since IE versions 10 and 11 use a version string that begins with "9.", th
    is simplistic parsing method works adequately. |  29    * Since IE versions 10 and 11 use a version string that begins with "9.", thi
    s simplistic parsing method works adequately. | 
|  26     */ |  30    */ | 
|  27   if (version[1] != '.' || version[0] < L'0' || version[0] > L'9') |  31   if (version.length() < 2 || version[1] != '.' || version[0] < L'0' || version[
    0] > L'9') | 
|  28   { |  32   { | 
|  29     throw std::runtime_error("IE version string has unexpected format"); |  33     throw std::runtime_error("IE version string has unexpected format"); | 
|  30   } |  34   } | 
|  31   if (version[0] != L'9') |  35   if (version[0] != L'9') | 
|  32   { |  36   { | 
|  33     return version; |  37     return version; | 
|  34   } |  38   } | 
|  35   // Assert the major version in the "Version" value is 9. |  39   // Assert the major version in the "Version" value is 9. | 
|  36   /* |  40   /* | 
|  37     * Version 9 might either be an actual version 9 or it might represent a vers
    ion >= 10 |  41    * Version 9 might either be an actual version 9 or it might represent a versi
    on >= 10 | 
|  38     * If the value named "svcVersion" exists, we'll report that instead. |  42    * If the value named "svcVersion" exists, we'll report that instead. | 
|  39     */ |  43    */ | 
|  40   try |  44   try | 
|  41   { |  45   { | 
|  42     return IE_key.value_wstring(L"svcVersion"); |  46     version = ieKey.value_wstring(L"svcVersion"); // throws if value not found | 
|  43   } |  47   } | 
|  44   catch (...) |  48   catch (...) | 
|  45   { |  49   { | 
 |  50     // Assert svcVersion value not found | 
 |  51     // Thus the major version is 9 | 
|  46     return version; |  52     return version; | 
 |  53   }  | 
 |  54   // Assert major version is >= 10 | 
 |  55   if (version.length() < 3 || version[0] < L'0' || version[0] > L'9' || version[
    1] < L'0' || version[1] > L'9' || version[2] != L'.') | 
 |  56   { | 
 |  57     throw std::runtime_error("IE version string has unexpected format"); | 
|  47   } |  58   } | 
 |  59   return version; | 
|  48 } |  60 } | 
|  49  |  61  | 
|  50 std::wstring AdblockPlus::IE::installed_version_string() |  62 std::wstring AdblockPlus::IE::InstalledVersionString() | 
|  51 { |  63 { | 
|  52   try |  64   try | 
|  53   { |  65   { | 
|  54     return IE_version_string(); |  66     return IeVersionString(); | 
|  55   } |  67   } | 
|  56   catch (...) |  68   catch (...) | 
|  57   { |  69   { | 
|  58     return L""; |  70     return L""; | 
|  59   } |  71   } | 
|  60 } |  72 } | 
|  61  |  73  | 
|  62 int AdblockPlus::IE::installed_major_version() |  74 int AdblockPlus::IE::InstalledMajorVersion() | 
|  63 { |  75 { | 
|  64   try |  76   try | 
|  65   { |  77   { | 
|  66     std::wstring version = IE_version_string(); |  78     std::wstring version = IeVersionString(); | 
|  67     /* |  79     /* | 
|  68      * If the second character is a period, we assume that the major version is 
    a single digit. |  80      * The version number is either one or two digits, | 
 |  81      *   and thus either the second or third character is a period, | 
|  69      */ |  82      */ | 
|  70     if (version[ 1 ] == L'.') |  83     if (version[1] == L'.') | 
|  71     { |  84     { | 
|  72       return version[ 0 ] - L'0'; |  85       return version[0] - L'0'; | 
 |  86     }  | 
 |  87     else if (version[2] == L'.') | 
 |  88     { | 
 |  89       return 10 * (version[0] - L'0') + (version[1] - L'0'); | 
|  73     } |  90     } | 
|  74     // Assert IE_version_string() did not verify the syntax of the version strin
    g. |  | 
|  75     /* |  | 
|  76      * In this case, we'll assume that the version returned is two digits follow
    ed by a period. |  | 
|  77      * If not, we'll assume an error. |  | 
|  78      */ |  | 
|  79     if (version[ 0 ] < L'0' || version[ 0 ] > L'9' || version[ 1 ] < L'0' || ver
    sion[ 1 ] > L'9' || version[ 2 ] != L'.') |  | 
|  80     { |  | 
|  81       return 0; |  | 
|  82     } |  | 
|  83     return 10 * (version[ 0 ] - L'0') + (version[ 1 ] - L'0'); |  | 
|  84   } |  91   } | 
|  85   catch (...) |  92   catch (...) | 
|  86   { |  93   { | 
|  87     return 0; |  | 
|  88   } |  94   } | 
 |  95   return 0; | 
|  89 } |  96 } | 
| LEFT | RIGHT |