From 64030a40ac98f5420e77cdb672dd428f22bbffd4 Mon Sep 17 00:00:00 2001 From: Matt Amos Date: Thu, 24 Nov 2011 22:15:43 +0000 Subject: [PATCH] Replace @ with ~ in the shortlink This should help Twitter's horribly broken URL detection algorithm not screw up shortlinks from OSM. --- app/assets/javascripts/site.js | 2 +- config/routes.rb | 2 +- lib/short_link.rb | 7 ++++++- test/unit/short_link_test.rb | 15 +++++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/site.js b/app/assets/javascripts/site.js index be16dd059..9f80bf25d 100644 --- a/app/assets/javascripts/site.js +++ b/app/assets/javascripts/site.js @@ -204,7 +204,7 @@ function interlace(x, y) { * Called to create a short code for the short link. */ function makeShortCode(lat, lon, zoom) { - char_array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_@"; + char_array = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_~"; var x = Math.round((lon + 180.0) * ((1 << 30) / 90.0)); var y = Math.round((lat + 90.0) * ((1 << 30) / 45.0)); // JavaScript only has to keep 32 bits of bitwise operators, so this has to be diff --git a/config/routes.rb b/config/routes.rb index cd7261cdf..0a617b6a3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -123,7 +123,7 @@ OpenStreetMap::Application.routes.draw do match '/forgot-password.html' => 'user#lost_password' # permalink - match '/go/:code' => 'site#permalink', :code => /[a-zA-Z0-9_@]+[=-]*/ + match '/go/:code' => 'site#permalink', :code => /[a-zA-Z0-9_@~]+[=-]*/ # traces match '/user/:display_name/traces/tag/:tag/page/:page' => 'trace#list' diff --git a/lib/short_link.rb b/lib/short_link.rb index b91d7e569..045883d57 100644 --- a/lib/short_link.rb +++ b/lib/short_link.rb @@ -9,7 +9,7 @@ module ShortLink # array of 64 chars to encode 6 bits. this is almost like base64 encoding, but # the symbolic chars are different, as base64's + and / aren't very # URL-friendly. - ARRAY = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + ['_','@'] + ARRAY = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + ['_','~'] ## # Given a string encoding a location, returns the [lon, lat, z] tuple of that @@ -20,6 +20,11 @@ module ShortLink z = 0 z_offset = 0 + # keep support for old shortlinks which use the @ character, now + # replaced by the ~ character because twitter is horribly broken + # and we can't have that. + str.gsub!("@","~") + str.each_char do |c| t = ARRAY.index c if t.nil? diff --git a/test/unit/short_link_test.rb b/test/unit/short_link_test.rb index bbae95106..cdc6b3cfd 100644 --- a/test/unit/short_link_test.rb +++ b/test/unit/short_link_test.rb @@ -23,4 +23,19 @@ class ShortLinkTest < ActiveSupport::TestCase assert max_distance > distance, "Maximum expected error exceeded: #{max_distance} <= #{distance} for (#{lat}, #{lon}, #{zoom})." end end + + ## + # test that links are backwards-compatible, so any old links with + # the deprecated @ characters in them still work properly. + def test_deprecated_at_sign + cases = [["~v2juONc--", "@v2juONc--"], + ["as3I3GpG~-", "as3I3GpG@-"], + ["D~hV--", "D@hV--"], + ["CO0O~m8--", "CO0O@m8--"]] + + cases.each do |new_code, old_code| + assert_equal ShortLink.decode(old_code), ShortLink.decode(new_code), + "old (#{old_code}) and new (#{new_code}) should decode to the same location." + end + end end -- 2.43.2