jekyll-l10n 1.1.7 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d59b40394ccd291d468bfd045b6b53ffd71204d6b42575f232e7159316c14561
|
|
4
|
+
data.tar.gz: c3c0bc5a22a1ce203a7623be5217f8477b9d4b57f39918ca221a10f693bbd053
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b022fa06243f0d8150be0f53bcbd9861751634fb1d3af4d5cd16ae36bf11cbfb19fd3e86e3af63cad783fea3d21f56338ad4f14cde2fb68165ffe6b9146e12ad
|
|
7
|
+
data.tar.gz: 74a6fa21f10fe87de0c8f891f9eedb77d36d0df2d50ccd23a794cc20d3a127c183ad6edd35b6284189beb7d0472928ee0bbea8a075fbdfd1abd016586354dbbc
|
|
@@ -114,8 +114,8 @@ module Jekyll
|
|
|
114
114
|
|
|
115
115
|
# Default behavior when LibreTranslate API returns an error
|
|
116
116
|
# If true, translation stops immediately. If false, continues with remaining entries.
|
|
117
|
-
# @return [Boolean]
|
|
118
|
-
DEFAULT_LIBRETRANSLATE_STOP_ON_ERROR =
|
|
117
|
+
# @return [Boolean] false
|
|
118
|
+
DEFAULT_LIBRETRANSLATE_STOP_ON_ERROR = false
|
|
119
119
|
|
|
120
120
|
# Default interval for logging LibreTranslate translation progress
|
|
121
121
|
# Progress is logged every N entries. Set to 0 to disable.
|
|
@@ -6,6 +6,7 @@ require_relative "logger"
|
|
|
6
6
|
require_relative "html_string_extractor"
|
|
7
7
|
require_relative "../utils/file_operations"
|
|
8
8
|
require_relative "../utils/site_config_accessor"
|
|
9
|
+
require_relative "../utils/error_handler"
|
|
9
10
|
|
|
10
11
|
module Jekyll
|
|
11
12
|
module L10n
|
|
@@ -99,7 +100,9 @@ module Jekyll
|
|
|
99
100
|
config = find_libretranslate_config
|
|
100
101
|
return unless config
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
ErrorHandler.handle_with_logging("machine translation") do
|
|
104
|
+
@result_saver.translate_compendia(config)
|
|
105
|
+
end
|
|
103
106
|
end
|
|
104
107
|
|
|
105
108
|
def process_file(file_path)
|
|
@@ -12,7 +12,8 @@ module Jekyll
|
|
|
12
12
|
# Key responsibilities:
|
|
13
13
|
# * Build paths for compendium PO files
|
|
14
14
|
# * Build paths for page-specific PO files
|
|
15
|
-
# * Handle file path normalization
|
|
15
|
+
# * Handle file path normalization and validation
|
|
16
|
+
# * Prevent path traversal attacks
|
|
16
17
|
#
|
|
17
18
|
# @example
|
|
18
19
|
# compendium = PoPathBuilder.build('_site', '_locales', 'es', nil)
|
|
@@ -25,16 +26,35 @@ module Jekyll
|
|
|
25
26
|
# For compendium (page_path nil): {source}/{locales_dir}/{locale}.po
|
|
26
27
|
# For page-specific: {source}/{locales_dir}/{locale}/{page_path}.po
|
|
27
28
|
#
|
|
29
|
+
# Validates that page_path doesn't escape the base directory using path
|
|
30
|
+
# traversal techniques (e.g., ../../../etc/passwd).
|
|
31
|
+
#
|
|
28
32
|
# @param source [String] Site source directory
|
|
29
33
|
# @param locales_dir [String] Locales directory name (e.g., '_locales')
|
|
30
34
|
# @param locale [String] Locale code (e.g., 'es', 'fr')
|
|
31
35
|
# @param page_path [String, nil] Page path for page-specific file, nil for compendium
|
|
32
36
|
# @return [String] Full path to PO file
|
|
37
|
+
# @raise [Jekyll::L10n::Errors::PoFileError] if page_path attempts to escape base directory
|
|
33
38
|
def self.build(source, locales_dir, locale, page_path)
|
|
34
39
|
if page_path.nil?
|
|
35
40
|
File.join(source, locales_dir, "#{locale}.po")
|
|
36
41
|
else
|
|
37
|
-
|
|
42
|
+
# Build the normal path
|
|
43
|
+
normal_path = File.join(source, locales_dir, locale, "#{page_path}.po")
|
|
44
|
+
|
|
45
|
+
# Validate against path traversal using expanded paths
|
|
46
|
+
base_path = File.expand_path(File.join(source, locales_dir))
|
|
47
|
+
expanded_path = File.expand_path(normal_path)
|
|
48
|
+
|
|
49
|
+
# Security: Validate path stays within base directory
|
|
50
|
+
valid_path = expanded_path.start_with?(base_path + File::SEPARATOR) ||
|
|
51
|
+
expanded_path == base_path
|
|
52
|
+
unless valid_path
|
|
53
|
+
raise Jekyll::L10n::Errors::PoFileError,
|
|
54
|
+
"Path traversal attempt detected in page_path: #{page_path}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
normal_path
|
|
38
58
|
end
|
|
39
59
|
end
|
|
40
60
|
end
|
|
@@ -198,6 +198,18 @@ module Jekyll
|
|
|
198
198
|
def make_api_request(text, target_locale)
|
|
199
199
|
uri = URI("#{@config.libretranslate_api_url}/translate")
|
|
200
200
|
Jekyll.logger.debug "LibreTranslator", "Requesting #{uri}"
|
|
201
|
+
request = build_request(uri, text, target_locale)
|
|
202
|
+
response = http_config.request(request)
|
|
203
|
+
Jekyll.logger.debug "LibreTranslator", "Response code: #{response.code}"
|
|
204
|
+
handle_api_response(response)
|
|
205
|
+
rescue Net::ReadTimeout, Net::OpenTimeout => e
|
|
206
|
+
raise TranslationError, "API timeout: #{e.message}"
|
|
207
|
+
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, SocketError => e
|
|
208
|
+
Jekyll.logger.warn "LibreTranslator", "#{e.class.name}: #{e.message}"
|
|
209
|
+
nil
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def build_request(uri, text, target_locale)
|
|
201
213
|
request = Net::HTTP::Post.new(uri, api_headers)
|
|
202
214
|
request.body = {
|
|
203
215
|
:q => text,
|
|
@@ -205,11 +217,7 @@ module Jekyll
|
|
|
205
217
|
:target => target_locale,
|
|
206
218
|
:format => @config.libretranslate_format,
|
|
207
219
|
}.to_json
|
|
208
|
-
|
|
209
|
-
Jekyll.logger.debug "LibreTranslator", "Response code: #{response.code}"
|
|
210
|
-
handle_api_response(response)
|
|
211
|
-
rescue Net::ReadTimeout, Net::OpenTimeout => e
|
|
212
|
-
raise TranslationError, "API timeout: #{e.message}"
|
|
220
|
+
request
|
|
213
221
|
end
|
|
214
222
|
|
|
215
223
|
def handle_api_response(response)
|
|
@@ -21,7 +21,7 @@ module Jekyll
|
|
|
21
21
|
class SiteConfigAccessor
|
|
22
22
|
# Extract localization configuration from site.
|
|
23
23
|
#
|
|
24
|
-
# Accesses the
|
|
24
|
+
# Accesses the with_locales_data configuration which contains the
|
|
25
25
|
# locales, extraction settings, and other localization options.
|
|
26
26
|
#
|
|
27
27
|
# @param site [Jekyll::Site, Hash] Jekyll site object or hash double
|