mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Do not traverse symlinks in heuristics (#3946)
This commit is contained in:
		| @@ -11,11 +11,13 @@ module Linguist | |||||||
|     # |     # | ||||||
|     # path    - A path String (does not necessarily exists on the file system). |     # path    - A path String (does not necessarily exists on the file system). | ||||||
|     # content - Content of the file. |     # content - Content of the file. | ||||||
|  |     # symlink - Whether the file is a symlink. | ||||||
|     # |     # | ||||||
|     # Returns a Blob. |     # Returns a Blob. | ||||||
|     def initialize(path, content) |     def initialize(path, content, symlink: false) | ||||||
|       @path = path |       @path = path | ||||||
|       @content = content |       @content = content | ||||||
|  |       @symlink = symlink | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     # Public: Filename |     # Public: Filename | ||||||
| @@ -69,5 +71,12 @@ module Linguist | |||||||
|         "." + segments[index..-1].join(".") |         "." + segments[index..-1].join(".") | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     # Public: Is this a symlink? | ||||||
|  |     # | ||||||
|  |     # Returns true or false. | ||||||
|  |     def symlink? | ||||||
|  |       @symlink | ||||||
|  |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -18,6 +18,8 @@ module Linguist | |||||||
|     # |     # | ||||||
|     # Returns an Array of Language objects, most probable first. |     # Returns an Array of Language objects, most probable first. | ||||||
|     def self.call(blob, possible_languages) |     def self.call(blob, possible_languages) | ||||||
|  |       return [] if blob.symlink? | ||||||
|  |  | ||||||
|       language_names = possible_languages.map(&:name) |       language_names = possible_languages.map(&:name) | ||||||
|       classify(Samples.cache, blob.data[0...CLASSIFIER_CONSIDER_BYTES], language_names).map do |name, _| |       classify(Samples.cache, blob.data[0...CLASSIFIER_CONSIDER_BYTES], language_names).map do |name, _| | ||||||
|         Language[name] # Return the actual Language objects |         Language[name] # Return the actual Language objects | ||||||
|   | |||||||
| @@ -26,6 +26,11 @@ module Linguist | |||||||
|       @mode ||= File.stat(@fullpath).mode.to_s(8) |       @mode ||= File.stat(@fullpath).mode.to_s(8) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     def symlink? | ||||||
|  |       return @symlink if !@symlink.nil? | ||||||
|  |       @symlink = (File.symlink?(@fullpath) rescue false) | ||||||
|  |     end | ||||||
|  |  | ||||||
|     # Public: Read file contents. |     # Public: Read file contents. | ||||||
|     # |     # | ||||||
|     # Returns a String. |     # Returns a String. | ||||||
|   | |||||||
| @@ -16,6 +16,8 @@ module Linguist | |||||||
|     # |     # | ||||||
|     # Returns an Array of languages, or empty if none matched or were inconclusive. |     # Returns an Array of languages, or empty if none matched or were inconclusive. | ||||||
|     def self.call(blob, candidates) |     def self.call(blob, candidates) | ||||||
|  |       return [] if blob.symlink? | ||||||
|  |  | ||||||
|       data = blob.data[0...HEURISTICS_CONSIDER_BYTES] |       data = blob.data[0...HEURISTICS_CONSIDER_BYTES] | ||||||
|  |  | ||||||
|       @heuristics.each do |heuristic| |       @heuristics.each do |heuristic| | ||||||
|   | |||||||
| @@ -80,6 +80,11 @@ module Linguist | |||||||
|       @size |       @size | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  |     def symlink? | ||||||
|  |       # We don't create LazyBlobs for symlinks. | ||||||
|  |       false | ||||||
|  |     end | ||||||
|  |  | ||||||
|     def cleanup! |     def cleanup! | ||||||
|       @data.clear if @data |       @data.clear if @data | ||||||
|     end |     end | ||||||
|   | |||||||
| @@ -11,6 +11,8 @@ module Linguist | |||||||
|     # Returns an Array with one Language if the blob has a shebang with a valid |     # Returns an Array with one Language if the blob has a shebang with a valid | ||||||
|     # interpreter, or empty if there is no shebang. |     # interpreter, or empty if there is no shebang. | ||||||
|     def self.call(blob, _ = nil) |     def self.call(blob, _ = nil) | ||||||
|  |       return [] if blob.symlink? | ||||||
|  |  | ||||||
|       Language.find_by_interpreter interpreter(blob.data) |       Language.find_by_interpreter interpreter(blob.data) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|   | |||||||
| @@ -109,6 +109,8 @@ module Linguist | |||||||
|       # Returns an Array with one Language if the blob has a Vim or Emacs modeline |       # Returns an Array with one Language if the blob has a Vim or Emacs modeline | ||||||
|       # that matches a Language name or alias. Returns an empty array if no match. |       # that matches a Language name or alias. Returns an empty array if no match. | ||||||
|       def self.call(blob, _ = nil) |       def self.call(blob, _ = nil) | ||||||
|  |         return [] if blob.symlink? | ||||||
|  |  | ||||||
|         header = blob.first_lines(SEARCH_SCOPE).join("\n") |         header = blob.first_lines(SEARCH_SCOPE).join("\n") | ||||||
|         footer = blob.last_lines(SEARCH_SCOPE).join("\n") |         footer = blob.last_lines(SEARCH_SCOPE).join("\n") | ||||||
|         Array(Language.find_by_alias(modeline(header + footer))) |         Array(Language.find_by_alias(modeline(header + footer))) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user