Commit efdfd328 authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Parse X-UA-Compatible correctly.

There can be multiple compat modes defined, separated by commas, but also surrounded by whitespace. The highest mode in the list is picked as the document mode, with 'edge' being the highest mode available. It stops as soon as an invalid mode is found in the list and returns whatever highest mode was found until then. Signed-off-by: 's avatarGabriel Ivăncescu <gabrielopcode@gmail.com>
parent 3301a8e3
...@@ -154,7 +154,7 @@ static BOOL read_compat_mode(HKEY key, compat_mode_t *r) ...@@ -154,7 +154,7 @@ static BOOL read_compat_mode(HKEY key, compat_mode_t *r)
if(status != ERROR_SUCCESS || type != REG_SZ) if(status != ERROR_SUCCESS || type != REG_SZ)
return FALSE; return FALSE;
return parse_compat_version(version, r); return parse_compat_version(version, r) != NULL;
} }
static BOOL WINAPI load_compat_settings(INIT_ONCE *once, void *param, void **context) static BOOL WINAPI load_compat_settings(INIT_ONCE *once, void *param, void **context)
......
...@@ -297,6 +297,7 @@ PRIVATE_TID_LIST ...@@ -297,6 +297,7 @@ PRIVATE_TID_LIST
} tid_t; } tid_t;
typedef enum { typedef enum {
COMPAT_MODE_INVALID = -1,
COMPAT_MODE_QUIRKS, COMPAT_MODE_QUIRKS,
COMPAT_MODE_IE5, COMPAT_MODE_IE5,
COMPAT_MODE_IE7, COMPAT_MODE_IE7,
...@@ -1253,7 +1254,7 @@ HRESULT set_task_timer(HTMLInnerWindow*,LONG,enum timer_type,IDispatch*,LONG*) D ...@@ -1253,7 +1254,7 @@ HRESULT set_task_timer(HTMLInnerWindow*,LONG,enum timer_type,IDispatch*,LONG*) D
HRESULT clear_task_timer(HTMLInnerWindow*,DWORD) DECLSPEC_HIDDEN; HRESULT clear_task_timer(HTMLInnerWindow*,DWORD) DECLSPEC_HIDDEN;
HRESULT clear_animation_timer(HTMLInnerWindow*,DWORD) DECLSPEC_HIDDEN; HRESULT clear_animation_timer(HTMLInnerWindow*,DWORD) DECLSPEC_HIDDEN;
BOOL parse_compat_version(const WCHAR*,compat_mode_t*) DECLSPEC_HIDDEN; const WCHAR *parse_compat_version(const WCHAR*,compat_mode_t*) DECLSPEC_HIDDEN;
const char *debugstr_mshtml_guid(const GUID*) DECLSPEC_HIDDEN; const char *debugstr_mshtml_guid(const GUID*) DECLSPEC_HIDDEN;
......
...@@ -412,15 +412,20 @@ static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode ...@@ -412,15 +412,20 @@ static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode
lock_document_mode(doc); lock_document_mode(doc);
} }
BOOL parse_compat_version(const WCHAR *version_string, compat_mode_t *r) static BOOL is_ua_compatible_delimiter(WCHAR c)
{
return !c || c == ';' || c == ',' || iswspace(c);
}
const WCHAR *parse_compat_version(const WCHAR *version_string, compat_mode_t *r)
{ {
DWORD version = 0; DWORD version = 0;
const WCHAR *p; const WCHAR *p;
for(p = version_string; '0' <= *p && *p <= '9'; p++) for(p = version_string; '0' <= *p && *p <= '9'; p++)
version = version * 10 + *p-'0'; version = version * 10 + *p-'0';
if((*p && *p != ';') || p == version_string) if(!is_ua_compatible_delimiter(*p) || p == version_string)
return FALSE; return NULL;
switch(version){ switch(version){
case 5: case 5:
...@@ -442,13 +447,14 @@ BOOL parse_compat_version(const WCHAR *version_string, compat_mode_t *r) ...@@ -442,13 +447,14 @@ BOOL parse_compat_version(const WCHAR *version_string, compat_mode_t *r)
default: default:
*r = version < 5 ? COMPAT_MODE_QUIRKS : COMPAT_MODE_IE11; *r = version < 5 ? COMPAT_MODE_QUIRKS : COMPAT_MODE_IE11;
} }
return TRUE; return p;
} }
static BOOL parse_ua_compatible(const WCHAR *p, compat_mode_t *r) static BOOL parse_ua_compatible(const WCHAR *p, compat_mode_t *r)
{ {
static const WCHAR ie_eqW[] = {'I','E','='}; static const WCHAR ie_eqW[] = {'I','E','='};
static const WCHAR edgeW[] = {'e','d','g','e'}; static const WCHAR edgeW[] = {'e','d','g','e'};
compat_mode_t mode = COMPAT_MODE_INVALID;
TRACE("%s\n", debugstr_w(p)); TRACE("%s\n", debugstr_w(p));
...@@ -456,15 +462,22 @@ static BOOL parse_ua_compatible(const WCHAR *p, compat_mode_t *r) ...@@ -456,15 +462,22 @@ static BOOL parse_ua_compatible(const WCHAR *p, compat_mode_t *r)
return FALSE; return FALSE;
p += 3; p += 3;
if(!wcsnicmp(p, edgeW, ARRAY_SIZE(edgeW))) { do {
p += ARRAY_SIZE(edgeW); while(iswspace(*p)) p++;
if(*p && *p != ';') if(!wcsnicmp(p, edgeW, ARRAY_SIZE(edgeW))) {
return FALSE; p += ARRAY_SIZE(edgeW);
*r = COMPAT_MODE_IE11; if(is_ua_compatible_delimiter(*p))
return TRUE; mode = COMPAT_MODE_IE11;
} break;
}else if(!(p = parse_compat_version(p, r)))
break;
if(mode < *r)
mode = *r;
while(iswspace(*p)) p++;
} while(*p++ == ',');
return parse_compat_version(p, r); *r = mode;
return mode != COMPAT_MODE_INVALID;
} }
void process_document_response_headers(HTMLDocumentNode *doc, IBinding *binding) void process_document_response_headers(HTMLDocumentNode *doc, IBinding *binding)
......
...@@ -11441,6 +11441,26 @@ static void test_document_mode(IHTMLDocument2 *doc2) ...@@ -11441,6 +11441,26 @@ static void test_document_mode(IHTMLDocument2 *doc2)
static void test_quirks_mode(void) static void test_quirks_mode(void)
{ {
static const struct {
const char *str;
unsigned expected_mode;
} tests[] = {
{ "9", 9 },
{ " \t9 ", 9 },
{ " 5 , 8 , 7", 8 },
{ " 8 , 7 , 5", 8 },
{ " 5 , 5 , 7", 7 },
{ " 5 , 9 , 7", 9 },
{ " 5, 7,9", 9 },
{ " 5, 7;9", 7 },
{ " 5, edge,8", 11 },
{ " 5, foo,8", 5 },
{ " 5, 8,foo", 8 },
{ " 5, ,,7", 5 },
{ " 5, , ,7", 5 },
};
unsigned i;
run_domtest("<html></html>", check_quirks_mode); run_domtest("<html></html>", check_quirks_mode);
run_domtest("<!DOCTYPE html>\n<html></html>", check_strict_mode); run_domtest("<!DOCTYPE html>\n<html></html>", check_strict_mode);
run_domtest("<!-- comment --><!DOCTYPE html>\n<html></html>", check_quirks_mode); run_domtest("<!-- comment --><!DOCTYPE html>\n<html></html>", check_quirks_mode);
...@@ -11455,15 +11475,14 @@ static void test_quirks_mode(void) ...@@ -11455,15 +11475,14 @@ static void test_quirks_mode(void)
if(!is_ie9plus) if(!is_ie9plus)
return; return;
expected_document_mode = 9; for(i = 0; i < ARRAY_SIZE(tests); i++) {
run_domtest("<!DOCTYPE html>\n" char buf[128];
"<html>" expected_document_mode = tests[i].expected_mode;
" <head>" sprintf(buf, "<!DOCTYPE html>\n<html><head>"
" <meta http-equiv=\"x-ua-compatible\" content=\"IE=9\" />" " <meta http-equiv=\"x-ua-compatible\" content=\"IE=%s\" />"
" </head>" "</head><body></body></html>", tests[i].str);
" <body>" run_domtest(buf, test_document_mode);
" </body>" }
"</html>", test_document_mode);
expected_document_mode = 8; expected_document_mode = 8;
run_domtest("<!DOCTYPE html>\n" run_domtest("<!DOCTYPE html>\n"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment