From c13f1154739eab1ce339c0fa7e6468a0889ffe75 Mon Sep 17 00:00:00 2001
From: BlackDex <black.dex@gmail.com>
Date: Mon, 4 Feb 2019 12:55:39 +0100
Subject: [PATCH] Fixed issue #380

 - Created a separate function for parsing the sizes attribute
 - Parsing sizes now with regex
 - Should work with any non-digit separator
---
 src/api/icons.rs | 41 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/src/api/icons.rs b/src/api/icons.rs
index 4fda717b..c7b38296 100644
--- a/src/api/icons.rs
+++ b/src/api/icons.rs
@@ -226,11 +226,10 @@ fn get_page_with_cookies(url: &str, cookie_str: &str) -> Result<Response, Error>
 /// ```
 fn get_icon_priority(href: &str, sizes: &str) -> u8 {
     // Check if there is a dimension set
-    if !sizes.is_empty() {
-        let dimensions: Vec<&str> = sizes.split('x').collect();
-        let width: u16 = dimensions[0].parse().unwrap();
-        let height: u16 = dimensions[1].parse().unwrap();
+    let (width, height) = parse_sizes(sizes);
 
+    // Check if there is a size given
+    if width != 0 && height != 0 {
         // Only allow square dimensions
         if width == height {
             // Change priority by given size
@@ -243,8 +242,9 @@ fn get_icon_priority(href: &str, sizes: &str) -> u8 {
             } else if width == 16 {
                 4
             } else {
-                100
+                5
             }
+        // There are dimensions available, but the image is not a square
         } else {
             200
         }
@@ -260,6 +260,37 @@ fn get_icon_priority(href: &str, sizes: &str) -> u8 {
     }
 }
 
+/// Returns a Tuple with the width and hight as a seperate value extracted from the sizes attribute
+/// It will return 0 for both values if no match has been found.
+///
+/// # Arguments
+/// * `sizes` - The size of the icon if available as a <width>x<height> value like 32x32.
+/// 
+/// # Example
+/// ```
+/// let (width, height) = parse_sizes("64x64"); // (64, 64)
+/// let (width, height) = parse_sizes("x128x128"); // (128, 128)
+/// let (width, height) = parse_sizes("32"); // (0, 0)
+/// ```
+fn parse_sizes(sizes: &str) -> (u16, u16) {
+    let mut width: u16 = 0;
+    let mut height: u16 = 0;
+
+    if !sizes.is_empty() {
+        match Regex::new(r"(?x)(\d+)\D*(\d+)").unwrap().captures(sizes.trim()) {
+            None => {},
+            Some(dimensions) => {
+                if dimensions.len() >= 3 {
+                    width = dimensions[1].parse::<u16>().unwrap_or_default();
+                    height = dimensions[2].parse::<u16>().unwrap_or_default();
+                }
+            },
+        }
+    }
+
+    (width, height)
+}
+
 fn download_icon(domain: &str) -> Result<Vec<u8>, Error> {
     let (url, cookie_str) = get_icon_url(&domain)?;