22// Copyright (c) 2025 LLC «V Kontakte»
33// Distributed under the GPL v3 License, see LICENSE.notice.txt
44
5+ #include " runtime-light/stdlib/file/file-system-functions.h"
6+
57#include < array>
68#include < cstddef>
79#include < cstdint>
10+ #include < cstring>
811#include < expected>
912#include < format>
13+ #include < iterator>
14+ #include < limits>
15+ #include < memory>
1016#include < optional>
1117#include < span>
1218#include < string_view>
1319#include < sys/stat.h>
20+ #include < utility>
1421
15- #include " runtime-common/core/allocator/runtime-allocator.h"
1622#include " runtime-common/core/allocator/script-malloc-interface.h"
1723#include " runtime-common/core/runtime-core.h"
1824#include " runtime-light/k2-platform/k2-api.h"
1925#include " runtime-light/stdlib/diagnostics/logs.h"
20- #include " runtime-light/stdlib/file/file-system-functions.h"
2126#include " runtime-light/stdlib/file/resource.h"
2227
2328namespace {
@@ -93,21 +98,26 @@ std::optional<image_info> get_gif_info(std::span<unsigned char> buf) noexcept {
9398 }};
9499}
95100
96- std::optional<image_info> get_jpg_info (size_t file_size, size_t read_size, std::span<unsigned char > buf, const string& name, kphp::fs::file file) noexcept {
101+ std::optional<image_info> get_jpg_info (uint64_t file_size, size_t read_size, std::span<unsigned char > buf, const string& name, kphp::fs::file file) noexcept {
102+ if (file_size > static_cast <uint64_t >(std::numeric_limits<size_t >::max ())) {
103+ kphp::log::warning (" size of jpg file \" {}\" is more, than {}" , name.c_str (), std::numeric_limits<size_t >::max ());
104+ return std::nullopt ;
105+ }
106+
97107 image_info info{.type = IMAGETYPE_JPEG};
98108
99109 std::unique_ptr<unsigned char , decltype (std::addressof (kphp::memory::script::free))> image_uniq_ptr{
100- static_cast <unsigned char *>(kphp::memory::script::alloc (file_size)), kphp::memory::script::free};
110+ static_cast <unsigned char *>(kphp::memory::script::alloc (static_cast < size_t >( file_size) )), kphp::memory::script::free};
101111 auto * image{image_uniq_ptr.get ()};
102112 if (image == nullptr ) {
103113 kphp::log::warning (" not enough memory to process file \" {}\" in getimagesize" , name.c_str ());
104114 return std::nullopt ;
105115 }
106116
107117 std::memcpy (image, buf.data (), read_size);
108- std::span<std::byte> image_span{std::next (reinterpret_cast <std::byte*>(image), read_size), file_size - read_size};
118+ std::span<std::byte> image_span{std::next (reinterpret_cast <std::byte*>(image), read_size), static_cast < size_t >( file_size) - read_size};
109119 std::expected<size_t , int32_t > read_res{file.read (std::as_writable_bytes (image_span))};
110- if (!read_res || *read_res < file_size - read_size) {
120+ if (!read_res || *read_res < static_cast < size_t >( file_size) - read_size) {
111121 return std::nullopt ;
112122 }
113123
@@ -120,7 +130,7 @@ std::optional<image_info> get_jpg_info(size_t file_size, size_t read_size, std::
120130 int32_t new_marker{};
121131
122132 do {
123- if (cur_pos == file_size) {
133+ if (cur_pos == static_cast < size_t >( file_size) ) {
124134 new_marker = M_EOI;
125135 break ;
126136 }
@@ -156,7 +166,7 @@ std::optional<image_info> get_jpg_info(size_t file_size, size_t read_size, std::
156166 case M_SOF13:
157167 case M_SOF14:
158168 case M_SOF15:
159- if (cur_pos + 8 > file_size) {
169+ if (cur_pos + 8 > static_cast < size_t >( file_size) ) {
160170 return std::nullopt ;
161171 }
162172 info.bits = image[cur_pos + 2 ];
@@ -172,7 +182,7 @@ std::optional<image_info> get_jpg_info(size_t file_size, size_t read_size, std::
172182 default :
173183 size_t length{static_cast <size_t >((image[cur_pos] << 8 ) + image[cur_pos + 1 ])};
174184
175- if (length < 2 || cur_pos + length > file_size) {
185+ if (length < 2 || cur_pos + length > static_cast < size_t >( file_size) ) {
176186 return std::nullopt ;
177187 }
178188 cur_pos += length;
@@ -195,8 +205,7 @@ std::optional<image_info> get_jpc_info(size_t read_size, std::span<unsigned char
195205 return std::nullopt ;
196206 }
197207
198- info.bits = 0 ;
199- for (int32_t i = 0 ; i < info.channels ; i++) {
208+ for (int32_t i{0 }; i < info.channels ; i++) {
200209 int32_t cur_bits{buf[42 + 3 * i]};
201210 if (cur_bits > info.bits ) {
202211 info.bits = cur_bits;
@@ -207,7 +216,7 @@ std::optional<image_info> get_jpc_info(size_t read_size, std::span<unsigned char
207216 return {info};
208217}
209218
210- std::optional<image_info> get_jpg_or_jpc_info (size_t file_size, size_t read_size, std::span<unsigned char > buf, const string& name,
219+ std::optional<image_info> get_jpg_or_jpc_info (uint64_t file_size, size_t read_size, std::span<unsigned char > buf, const string& name,
211220 kphp::fs::file file) noexcept {
212221 if (!std::strncmp (reinterpret_cast <const char *>(buf.data ()), php_sig_jpg.begin (), sizeof (php_sig_jpg))) {
213222 return get_jpg_info (file_size, read_size, buf, name, std::move (file));
@@ -218,7 +227,7 @@ std::optional<image_info> get_jpg_or_jpc_info(size_t file_size, size_t read_size
218227 }
219228}
220229
221- std::optional<image_info> get_jp2_info (size_t file_size, size_t read_size, std::span<unsigned char > buf, kphp::fs::file file) noexcept {
230+ std::optional<image_info> get_jp2_info (uint64_t file_size, size_t read_size, std::span<unsigned char > buf, kphp::fs::file file) noexcept {
222231 if (read_size < 54 || std::strncmp (reinterpret_cast <const char *>(buf.data ()), php_sig_jp2.begin (), sizeof (php_sig_jp2)) != 0 ) {
223232 return std::nullopt ;
224233 }
@@ -229,9 +238,9 @@ std::optional<image_info> get_jp2_info(size_t file_size, size_t read_size, std::
229238
230239 bool found{false };
231240 int32_t buf_pos{12 };
232- size_t file_pos{12 };
241+ uint64_t file_pos{12 };
233242 while (static_cast <int32_t >(read_size) >= 42 + buf_pos + 8 ) {
234- const unsigned char * s{buf.data () + buf_pos};
243+ const unsigned char * s{std::next ( buf.data (), buf_pos) };
235244 int32_t box_length{(s[0 ] << 24 ) + (s[1 ] << 16 ) + (s[2 ] << 8 ) + s[3 ]};
236245 if (box_length == 1 || box_length > 1000000000 ) {
237246 break ;
@@ -248,8 +257,7 @@ std::optional<image_info> get_jp2_info(size_t file_size, size_t read_size, std::
248257 break ;
249258 }
250259
251- info.bits = 0 ;
252- for (int32_t i = 0 ; i < info.channels ; i++) {
260+ for (int32_t i{0 }; i < info.channels ; i++) {
253261 int32_t cur_bits{s[42 + 3 * i]};
254262 if (cur_bits > info.bits ) {
255263 info.bits = cur_bits;
@@ -265,19 +273,19 @@ std::optional<image_info> get_jp2_info(size_t file_size, size_t read_size, std::
265273 break ;
266274 }
267275 file_pos += box_length;
268- if (file_pos >= file_size || static_cast < off_t >(file_pos) != static_cast < ssize_t >(file_pos) || static_cast < ssize_t >(file_pos) < 0 ) {
276+ if (file_pos >= file_size) {
269277 break ;
270278 }
271279
272280 read_size = MAX_READ_SIZE;
273- if (file_size - file_pos < MAX_READ_SIZE) {
274- read_size = file_size - file_pos;
281+ if (file_size - file_pos < static_cast < uint64_t >( MAX_READ_SIZE) ) {
282+ read_size = static_cast < size_t >( file_size - file_pos) ;
275283 }
276284 if (read_size < 50 ) {
277285 break ;
278286 }
279287 std::span<std::byte> buf_read_span{reinterpret_cast <std::byte*>(buf.data ()), read_size};
280- std::expected<size_t , int32_t > read_res{file.pread (std::as_writable_bytes (buf_read_span), static_cast < uint64_t >( file_pos) )};
288+ std::expected<size_t , int32_t > read_res{file.pread (std::as_writable_bytes (buf_read_span), file_pos)};
281289 if (!read_res || *read_res < read_size) {
282290 break ;
283291 }
@@ -316,8 +324,8 @@ mixed f$getimagesize(const string& name) noexcept {
316324 kphp::log::warning (" regular file expected as first argument in function getimagesize, \" {}\" is given" , name.c_str ());
317325 return false ;
318326 }
319- size_t file_size{static_cast <size_t >(stat_buf.st_size )};
320- if (file_size < MIN_FILE_SIZE) {
327+ uint64_t file_size{static_cast <uint64_t >(stat_buf.st_size )};
328+ if (file_size < static_cast < uint64_t >( MIN_FILE_SIZE) ) {
321329 return false ;
322330 }
323331
@@ -328,8 +336,8 @@ mixed f$getimagesize(const string& name) noexcept {
328336 auto file{std::move (*open_res)};
329337
330338 size_t read_size{MAX_READ_SIZE};
331- if (file_size < MAX_READ_SIZE) {
332- read_size = file_size;
339+ if (file_size < static_cast < uint64_t >( MAX_READ_SIZE) ) {
340+ read_size = static_cast < size_t >( file_size) ;
333341 }
334342 std::array<unsigned char , MAX_READ_SIZE> buf{};
335343 std::span<std::byte> buf_span{reinterpret_cast <std::byte*>(buf.begin ()), MAX_READ_SIZE};
0 commit comments