Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1276
diff -u -p -r1.1276 common.inc
--- includes/common.inc	15 Dec 2010 23:50:56 -0000	1.1276
+++ includes/common.inc	17 Dec 2010 13:49:40 -0000
@@ -271,19 +271,19 @@ function drupal_get_rdf_namespaces() {
  * This function can be called as long the headers aren't sent. Pass no
  * arguments (or NULL for both) to retrieve the currently stored elements.
  *
- * @param $data
+ * @param $element
  *   A renderable array. If the '#type' key is not set then 'html_tag' will be
  *   added as the default '#type'.
  * @param $key
  *   A unique string key to allow implementations of hook_html_head_alter() to
- *   identify the element in $data. Required if $data is not NULL.
+ *   identify the element in $element. Required if $element is not NULL.
  *
  * @return
  *   An array of all stored HEAD elements.
  *
  * @see theme_html_tag()
  */
-function drupal_add_html_head($data = NULL, $key = NULL) {
+function drupal_add_html_head($element = NULL, $key = NULL) {
   $stored_head = &drupal_static(__FUNCTION__);
 
   if (!isset($stored_head)) {
@@ -291,11 +291,11 @@ function drupal_add_html_head($data = NU
     $stored_head = _drupal_default_html_head();
   }
 
-  if (isset($data) && isset($key)) {
-    if (!isset($data['#type'])) {
-      $data['#type'] = 'html_tag';
+  if (isset($element) && isset($key)) {
+    if (!isset($element['#type'])) {
+      $element['#type'] = 'html_tag';
     }
-    $stored_head[$key] = $data;
+    $stored_head[$key] = $element;
   }
   return $stored_head;
 }
Index: modules/path/path.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/path/path.module,v
retrieving revision 1.187
diff -u -p -r1.187 path.module
--- modules/path/path.module	1 Dec 2010 00:31:38 -0000	1.187
+++ modules/path/path.module	17 Dec 2010 14:02:20 -0000
@@ -50,6 +50,27 @@ function path_permission() {
 }
 
 /**
+ * Implements hook_page_build().
+ */
+function path_page_build() {
+  if (drupal_get_path_alias() != $_GET['q']) {
+    $elements = drupal_add_html_head();
+    // drupal_add_html_head_link() appends the link href to the element key for
+    // some unknown/weird reason.
+    $found = FALSE;
+    foreach ($elements as $key => $element) {
+      if (strpos($key, 'drupal_add_html_head_link:canonical:') === 0) {
+        $found = TRUE;
+        break;
+      }
+    }
+    if (!$found) {
+      drupal_add_html_head_link(array('rel' => 'canonical', 'href' => url($_GET['q']), TRUE);
+    }
+  }
+}
+
+/**
  * Implements hook_menu().
  */
 function path_menu() {
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.999
diff -u -p -r1.999 system.module
--- modules/system/system.module	15 Dec 2010 02:59:01 -0000	1.999
+++ modules/system/system.module	17 Dec 2010 14:07:45 -0000
@@ -1935,6 +1935,15 @@ function system_custom_theme() {
 }
 
 /**
+ * Implements hook_page_build().
+ */
+function system_page_build() {
+  if (drupal_is_front_page()) {
+    drupal_add_html_head_link(array('rel' => 'canonical', 'href' => url($_GET['q']), TRUE);
+  }
+}
+
+/**
  * Implements hook_form_FORM_ID_alter().
  */
 function system_form_user_profile_form_alter(&$form, &$form_state) {
