webloc 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9a56c2bca20e777c569936514d7ee8bc96fb683a7a2bd2f22b4cd5b031b6aaf
4
- data.tar.gz: 3021c05bc2d572d30e7733ba046564be363631d563be0308aa07ee109ee0eaa7
3
+ metadata.gz: 498d11e48961e5843a3a25fafb71f4738ebc10733037145ea30a17f176abcaa2
4
+ data.tar.gz: 78beeadfdafd1a7f414fc6f7b69c6fd24819ed79bb39a9148e72e1bc38089416
5
5
  SHA512:
6
- metadata.gz: f559ba319ffe258097182613651c7b700d828635ef70dab3bb38f0d0fba29892425e42af10a90bd955d21ca18744e9498dc9146f63bf59d7ef09b233ccc22b29
7
- data.tar.gz: 8a5f22e11f55d1f80875bb471a095bbcd8348baeecc0c50ae8f5dad3e115cc04f22270b1055bf247e43698d4fae120001dc3dcb58eb6ae1d359c13d968bdf8b2
6
+ metadata.gz: 99b273c4af784bdafe2cde8166da2c3672a263d2e412f0f1547e70ef4b8bf8de74185a13b1050e5c16b713e3f7b8c67baabe9f25b1366ee4e86876a95a368740
7
+ data.tar.gz: fdbd68bb1239b9b35b1eb8c3d3ef8302d69d8a48eca6830bf636eb693f6e8c9a35e19af02148fda21a2d5a2ce3be1e3b7bef8186d7917dd8c40f73a699557e60
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  pkg/*
2
2
  *.gem
3
3
  .bundle
4
+ .DS_Store
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2011-2024 Peter Cooper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # webloc
2
2
 
3
- *webloc* is a Ruby library that can read from and write to <tt>.webloc</tt> files as used on macOS.
3
+ *webloc* is a Ruby library that can read from and write to <tt>.webloc</tt> files as used on macOS. These are a variant of 'plist' format files, specifically used for storing links to URLs.
4
4
 
5
- It works on Ruby 1.8.7 and up, including Ruby 3.x. It appears to still work on macOS Monterey too, so I have made a quick tidy up and release for 2022!
5
+ It works on Ruby 2.7 and up, including Ruby 3.x, and supports URLs of up to 2048 characters in length (and probably longer, but this is around the de facto limit for URLs in most systems).
6
6
 
7
7
  ## Installation
8
8
 
@@ -18,8 +18,13 @@ Writing to a .webloc file:
18
18
 
19
19
  Webloc.new('https://rubyweekly.com/').save('rubyweekly.webloc')
20
20
 
21
+ ## Thanks
22
+
23
+ Thanks is due to Christos Karaiskos for [this article](https://medium.com/@karaiskc/understanding-apples-binary-property-list-format-281e6da00dbd
24
+ ) which helped me understand the plist format a bit more when fixing a bug in 2024.
25
+
21
26
  ## License
22
27
 
23
- Copyright (C) 2011-2022 Peter Cooper
28
+ Copyright (C) 2011-2024 Peter Cooper
24
29
 
25
30
  webloc is licensed under the terms of the MIT License
@@ -1,3 +1,3 @@
1
1
  class Webloc
2
- VERSION = "0.1.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/webloc.rb CHANGED
@@ -13,9 +13,16 @@ class Webloc
13
13
 
14
14
  if data !~ /\<plist/
15
15
  offset = (data =~ /SURL_/)
16
- length = data[offset + 6]
17
- length = length.ord rescue length
18
- url = data[offset + 7,length]
16
+ length_offset = 7
17
+ if data[offset + 5] == "\x10"
18
+ length = data[offset + 6]
19
+ length = length.unpack('C')[0]
20
+ elsif data[offset + 5] == "\x11"
21
+ length_offset = 8
22
+ length = data[offset + 6] + data[offset + 7]
23
+ length = length.unpack('S>')[0]
24
+ end
25
+ url = data[offset + length_offset,length]
19
26
  else
20
27
  url = Plist::parse_xml(filename)['URL'] rescue nil
21
28
  end
@@ -25,11 +32,44 @@ class Webloc
25
32
  end
26
33
 
27
34
  def data
28
- @data = "\x62\x70\x6C\x69\x73\x74\x30\x30\xD1\x01\x02\x53\x55\x52\x4C\x5F\x10"
29
- @data += @url.length.chr
30
- @data += @url
31
- @data += "\x08\x0B\x0F\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
32
- @data += (@url.length + 18).chr
35
+ # PLIST HEADER
36
+ @data = "bplist\x30\x30".bytes
37
+
38
+ # PLIST OBJECT TABLE
39
+ @data += "\xD1\x01\x02".bytes # object 1 is a dictionary
40
+ @data += "SURL".bytes # object 2
41
+
42
+ length_suffix = @url.length > 255 ? "\x11" : "\x10"
43
+ @data += ("\x5f" + length_suffix).bytes # object 3 is an ASCII string with a variable length length encoding (I know..)
44
+ # .. the '0' in \x10 denotes the length can be encoded within 2**0 bytes (i.e. 1)
45
+ # .. the '1' in \x11 denotes the length can be encoded within 2**1 bytes (i.e. 2)
46
+
47
+ if @url.length > 255
48
+ @data += [@url.length].pack('S>').bytes
49
+ else
50
+ @data += [@url.length].pack('C').bytes
51
+ end
52
+ @data += @url.bytes # and finally the URL itself
53
+
54
+ # This is the offset table
55
+ @data += "\x08\x0B\x0F".bytes # so objects at 0x08, 0x0b and 0x0f
56
+
57
+ # PLIST TRAILER
58
+ # Bytes 0-4 are unused
59
+ @data += "\x00\x00\x00\x00\x00".bytes
60
+ # Byte 5 is the sort version
61
+ @data += "\x00".bytes
62
+ # Byte 6 is how many bytes are needed for each offset table offset
63
+ @data += "\x01".bytes
64
+ @data += "\x01".bytes
65
+ # Bytes 8-15 are how many objects are contained in the plist
66
+ @data += "\x00\x00\x00\x00\x00\x00\x00\x03".bytes
67
+ # Bytes 16-23 are for an offset from the offset table
68
+ @data += "\x00\x00\x00\x00\x00\x00\x00\x00".bytes
69
+ # Bytes 24-31 denote the position of the offset table from the start of the file
70
+ @data += "\x00\x00\x00\x00\x00\x00".bytes + [@url.length + 18].pack('S>').bytes
71
+
72
+ @data = @data.pack('C*')
33
73
  end
34
74
 
35
75
  def save(filename)
data/test/webloc_test.rb CHANGED
@@ -20,18 +20,31 @@ class WeblocTest < Test::Unit::TestCase
20
20
  end
21
21
 
22
22
  def test_webloc_generates_valid_data
23
- data = File.read(File.dirname(__FILE__) + '/oldstyle.webloc')
23
+ data = File.read(File.dirname(__FILE__) + '/oldstyle.webloc').b
24
24
  assert_equal data, Webloc.new('https://github.com/peterc/webloc').data
25
25
  end
26
26
 
27
+ def test_webloc_can_handle_long_urls
28
+ url = "http://example.com/this-is-a-very-long-url-abcde" + ('a' * 2000)
29
+ assert_nothing_raised { Webloc.new(url).data }
30
+ file = Tempfile.new('test-long-webloc')
31
+ begin
32
+ Webloc.new(url).save(file.path)
33
+ assert_equal url, Webloc.load(file.path).url
34
+ ensure
35
+ file.close
36
+ file.unlink
37
+ end
38
+ end
39
+
27
40
  def test_webloc_can_write_file
28
41
  file = Tempfile.new('test-webloc')
29
42
  begin
30
43
  Webloc.new('https://github.com/peterc/webloc').save(file.path)
31
- assert_equal Webloc.new('https://github.com/peterc/webloc').data, File.read(file.path)
44
+ assert_equal Webloc.new('https://github.com/peterc/webloc').data, File.read(file.path).b
32
45
  ensure
33
- file.close
34
- file.unlink
46
+ file.close
47
+ file.unlink
35
48
  end
36
49
  end
37
50
  end
data/webloc.gemspec CHANGED
@@ -7,10 +7,10 @@ Gem::Specification.new do |s|
7
7
  s.version = Webloc::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Peter Cooper"]
10
- s.email = ["peter@petercooper.co.uk"]
11
- s.homepage = "http://github.com/peterc/webloc"
12
- s.summary = %q{Reads and writes .webloc files on OS X}
13
- s.description = %q{Webloc reads and writes .webloc files on OS X}
10
+ s.email = ["git@peterc.org"]
11
+ s.homepage = "https://github.com/peterc/webloc"
12
+ s.summary = %q{Reads and writes .webloc files on macOS}
13
+ s.description = %q{Webloc reads and writes .webloc files on macOS}
14
14
 
15
15
  s.rubyforge_project = "webloc"
16
16
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webloc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Cooper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-04 00:00:00.000000000 Z
11
+ date: 2024-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: plist
@@ -24,15 +24,16 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- description: Webloc reads and writes .webloc files on OS X
27
+ description: Webloc reads and writes .webloc files on macOS
28
28
  email:
29
- - peter@petercooper.co.uk
29
+ - git@peterc.org
30
30
  executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
34
  - ".gitignore"
35
35
  - Gemfile
36
+ - LICENSE
36
37
  - README.md
37
38
  - Rakefile
38
39
  - lib/webloc.rb
@@ -41,7 +42,7 @@ files:
41
42
  - test/pliststyle.webloc
42
43
  - test/webloc_test.rb
43
44
  - webloc.gemspec
44
- homepage: http://github.com/peterc/webloc
45
+ homepage: https://github.com/peterc/webloc
45
46
  licenses: []
46
47
  metadata: {}
47
48
  post_install_message:
@@ -59,10 +60,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
60
  - !ruby/object:Gem::Version
60
61
  version: '0'
61
62
  requirements: []
62
- rubygems_version: 3.2.22
63
+ rubygems_version: 3.5.3
63
64
  signing_key:
64
65
  specification_version: 4
65
- summary: Reads and writes .webloc files on OS X
66
+ summary: Reads and writes .webloc files on macOS
66
67
  test_files:
67
68
  - test/oldstyle.webloc
68
69
  - test/pliststyle.webloc