From f962a0ab757ce558253667bac0761861a294f48a Mon Sep 17 00:00:00 2001 From: imsamuka Date: Sun, 2 Jan 2022 18:04:05 -0300 Subject: [PATCH] make youtube url validation safer --- src/glue/song.cr | 5 +++-- src/search/youtube.cr | 38 +++++++++++++------------------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/glue/song.cr b/src/glue/song.cr index 89ee737..008759e 100755 --- a/src/glue/song.cr +++ b/src/glue/song.cr @@ -115,8 +115,9 @@ class Song outputter("url", 1) else outputter("url", 2) - if !Youtube.is_valid_url(url) - raise("The url '#{url}' is an invalid youtube URL " + + url = Youtube.validate_url(url) + if !url + raise("The url is an invalid youtube URL " + "Check the URL and try again") end outputter("url", 3) diff --git a/src/search/youtube.cr b/src/search/youtube.cr index 051adca..5fd83ba 100755 --- a/src/search/youtube.cr +++ b/src/search/youtube.cr @@ -170,45 +170,33 @@ module Youtube return video_metadata end - # Checks if the given URL is a valid youtube URL + # Returns as a valid URL if possible # # ``` - # Youtube.is_valid_url("https://www.youtube.com/watch?v=NOTANACTUALVIDEOID") - # => false + # Youtube.validate_url("https://www.youtube.com/watch?v=NOTANACTUALVIDEOID") + # => nil # ``` - def is_valid_url(url : String) : Bool + def validate_url(url : String) : String | Nil uri = URI.parse url + return nil if !uri - # is it a video on youtube, with a query query = uri.query - - if !uri || !query || !uri.host || uri.path != "/watch" || - !uri.host.not_nil!.ends_with?("youtube.com") - return false - end - - - queries = query.split('&') + return nil if !query # find the video ID - i = 0 - while i < queries.size - if queries[i].starts_with?("v=") - vID = queries[i][2..-1] - break + vID = nil + query.split('&').each do |q| + if q.starts_with?("v=") + vID = q[2..-1] end - i += 1 - end - - if !vID - return false end + return nil if !vID + url = "https://www.youtube.com/watch?v=#{vID}" # this is an internal endpoint to validate the video ID - response = HTTP::Client.get "https://www.youtube.com/oembed?format=json&url=#{url}" - return response.success? + return response.success? ? url : nil end end