<html>
<!--

   DOM checker - test target page
   ------------------------------

   Authors: Michal Zalewski <lcamtuf@google.com>
            Filipe Almeida <filipe@google.com>

   Copyright 2008 by Google Inc. All Rights Reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

-->

<script src="dom_config.js"></script>

<script>

var private_var = 1;		// We'll try to set it across domains.
var ipc_page;			// IPC page location
var queue_timer;		// IPC queue handling timer
var idle = true;		// IPC handler state
var prev_hval = 'NONE';		// Previous IPC command
var idle_cycles = 0;		// Number of cycles spend in idle

/* Try to inject a variable to paren't namespace by defining a getter in
   another domain. */

try {
  top.__defineGetter__('injected_var', function() {return 1;})
} catch(e) {}


/* Update IPC frame location as needed, set timers. */
function page_init() {

  ipc_page = 'http://' + main_host + '/' + main_dir + '/dom_blank_page.html';
  document.getElementById('ipc_write').src = ipc_page + '#2';

  // log('Local ipc_write initialized to ' + ipc_page);

  queue_timer = setInterval('get_ipc_command()',250);

}


/* IPC subsystem logging (debugging purposes only) */
function log(x) {
  var e = document.createElement('li');
  e.innerHTML = x;
  document.getElementById('log').appendChild(e);
}


/* Wait for IPC state change, execute command, send results. */
function get_ipc_command() {

  var hval;

  try { hval = top.frames['ipc_read'].location.hash; } catch (e) {
    // log('IPC command read failed from external ipc_read.');
    hval = '';
  }

  if (hval == prev_hval || hval == '' || hval == undefined || hval == 'NONE') {
    if (!idle) {
      idle_cycles++;

      if (idle_cycles == 200) {
        // log('Entered power saving mode.');
        clearInterval(queue_timer);
        queue_timer = setInterval('get_ipc_command()',250);
        idle = true;
      }

    }

    return;
  }

  /* Full speed! */
  if (idle) {
    // log('Entered full speed mode.');
    clearInterval(queue_timer);
    queue_timer = setInterval('get_ipc_command()',1);
    idle = false;
    idle_cycles = 0;
  }

  // log('Got IPC command ' + hval + ' (prev: ' + prev_hval + ')');

  prev_hval = hval;

  var res = 0;

  hval = hval.substr(1);

  if (hval == 'RESET') res = 2;
  else try {
    if (eval(unescape(hval))) res = 1;
   } catch (e) {
    // log('Evaluation exception! Final was: ' + unescape(hval));
  }

  document.getElementById('ipc_write').src =  ipc_page + '#' + res;

}

</script>
<title>DOM checker victim page</title>
<body onload="page_init()">

<!-- Some bogus page elements to make it possible to enumerate arrays. -->

<style name=ns>MENU { margin: 1em }</style>

<img src="#bad" name=ni>

<form name=nf method=post action=foo>
<input type=hidden name=foo value=bar>
</form>

<h1><a href="#bad" name=nl>Hi mom!</a></h1>

<a name=ni2>

<embed name=ne></embed>

<object name=no></object>

<applet name=na></applet>

<!-- Log container -->
<div id=log>
</div>

<!-- Nested subframe used for about:blank tests -->
<iframe id=nf name=nf src="about:blank">
</iframe>

<!-- IPC frame -->
<iframe id=ipc_write name=ipc_write></iframe>

