Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c9c7cea

Browse files
committedDec 11, 2024·
Implement jerry_port_path_normalize in a more reliable way
Replace jerry_port_path_normalize,jerry_port_path_free,jerry_port_path_base with jerry_port_path_style,jerry_port_get_cwd Partially fixes jerryscript-project#4979 Closes: jerryscript-project#4983 JerryScript-DCO-1.0-Signed-off-by: Yonggang Luo [email protected]
1 parent aa7861d commit c9c7cea

File tree

10 files changed

+734
-215
lines changed

10 files changed

+734
-215
lines changed
 

‎docs/05.PORT-API.md

+15-34
Original file line numberDiff line numberDiff line change
@@ -163,52 +163,33 @@ void jerry_port_line_free (jerry_char_t *buffer_p);
163163

164164
## Filesystem
165165

166-
```
167-
/**
168-
* Canonicalize a file path.
169-
*
170-
* If possible, the implementation should resolve symbolic links and other directory references found in the input path,
171-
* and create a fully canonicalized file path as the result.
172-
*
173-
* The function may return with NULL in case an error is encountered, in which case the calling operation will not
174-
* proceed.
175-
*
176-
* The implementation should allocate storage for the result path as necessary. Non-NULL return values will be passed
177-
* to `jerry_port_path_free` when the result is no longer needed by the caller, which can be used to finalize
178-
* dynamically allocated buffers.
179-
*
180-
* NOTE: The implementation must not return directly with the input, as the input buffer is released after the call.
181-
*
182-
* @param path_p: zero-terminated string containing the input path
183-
* @param path_size: size of the input path string in bytes, excluding terminating zero
184-
*
185-
* @return buffer with the normalized path if the operation is successful,
186-
* NULL otherwise
187-
*/
188-
jerry_char_t *jerry_port_path_normalize (const jerry_char_t *path_p, jerry_size_t path_size);
189-
```
190-
191166
```c
192167
/**
193-
* Free a path buffer returned by jerry_port_path_normalize.
168+
* Get the path style of the current OS
194169
*
195-
* @param path_p: the path buffer to free
170+
* @return path style
196171
*/
197-
void jerry_port_path_free (jerry_char_t *path_p);
172+
jerry_path_style_t jerry_port_path_style (void);
198173
```
199174
200175
```c
201176
/**
202-
* Get the offset of the basename component in the input path.
177+
* Get the cwd, the output string will be zero-terminated
203178
*
204-
* The implementation should return the offset of the first character after the last path separator found in the path.
205-
* This is used by the caller to split the path into a directory name and a file name.
179+
* @param buffer_p: the buffer to storage the cwd
180+
* @param buffer_size: the `buffer_p` buffer size, including '\0` terminator
206181
*
207-
* @param path_p: input zero-terminated path string
182+
* @note
183+
* - cwd: current working directory
208184
*
209-
* @return offset of the basename component in the input path
185+
* @return The length of cwd, excluding '\0' terminator
186+
* - When buffer_p is `NULL` and get cwd succeed return length of cwd
187+
* - When buffer_p is `NULL` and get cwd failed return 0
188+
* - When buffer_p is not `NULL` and the `buffer_size - 1` just equal to
189+
* length of cwd; and get cwd succeed return `buffer_size - 1`.
190+
* - Otherwise means get cwd failed and return 0
210191
*/
211-
jerry_size_t jerry_port_path_base (const jerry_char_t *path_p);
192+
jerry_size_t jerry_port_get_cwd (jerry_char_t *buffer_p, jerry_size_t buffer_size);
212193
```
213194

214195
```c

‎jerry-core/api/jerry-module.c

+571-7
Large diffs are not rendered by default.

‎jerry-core/include/jerryscript-port.h

+24-32
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ JERRY_C_API_BEGIN
3737
* @{
3838
*/
3939

40+
/**
41+
* The path style of the OS
42+
*/
43+
typedef enum
44+
{
45+
JERRY_PATH_STYLE_WINDOWS,
46+
JERRY_PATH_STYLE_POSIX,
47+
} jerry_path_style_t;
48+
4049
/**
4150
* Error codes that can be passed by the engine when calling jerry_port_fatal
4251
*/
@@ -191,46 +200,29 @@ void jerry_port_line_free (jerry_char_t *buffer_p);
191200
*/
192201

193202
/**
194-
* Canonicalize a file path.
195-
*
196-
* If possible, the implementation should resolve symbolic links and other directory references found in the input path,
197-
* and create a fully canonicalized file path as the result.
198-
*
199-
* The function may return with NULL in case an error is encountered, in which case the calling operation will not
200-
* proceed.
201-
*
202-
* The implementation should allocate storage for the result path as necessary. Non-NULL return values will be passed
203-
* to `jerry_port_path_free` when the result is no longer needed by the caller, which can be used to finalize
204-
* dynamically allocated buffers.
205-
*
206-
* NOTE: The implementation must not return directly with the input, as the input buffer is released after the call.
207-
*
208-
* @param path_p: zero-terminated string containing the input path
209-
* @param path_size: size of the input path string in bytes, excluding terminating zero
210-
*
211-
* @return buffer with the normalized path if the operation is successful,
212-
* NULL otherwise
213-
*/
214-
jerry_char_t *jerry_port_path_normalize (const jerry_char_t *path_p, jerry_size_t path_size);
215-
216-
/**
217-
* Free a path buffer returned by jerry_port_path_normalize.
203+
* Get the path style of the current OS
218204
*
219-
* @param path_p: the path buffer to free
205+
* @return path style
220206
*/
221-
void jerry_port_path_free (jerry_char_t *path_p);
207+
jerry_path_style_t jerry_port_path_style (void);
222208

223209
/**
224-
* Get the offset of the basename component in the input path.
210+
* Get the cwd, the output string will be zero-terminated
225211
*
226-
* The implementation should return the offset of the first character after the last path separator found in the path.
227-
* This is used by the caller to split the path into a directory name and a file name.
212+
* @param buffer_p: the buffer to storage the cwd
213+
* @param buffer_size: the `buffer_p` buffer size, including '\0` terminator
228214
*
229-
* @param path_p: input zero-terminated path string
215+
* @note
216+
* - cwd: current working directory
230217
*
231-
* @return offset of the basename component in the input path
218+
* @return The length of cwd, excluding '\0' terminator
219+
* - When buffer_p is `NULL` and get cwd succeed return length of cwd
220+
* - When buffer_p is `NULL` and get cwd failed return 0
221+
* - When buffer_p is not `NULL` and the `buffer_size - 1` just equal to
222+
* length of cwd; and get cwd succeed return `buffer_size - 1`.
223+
* - Otherwise means get cwd failed and return 0
232224
*/
233-
jerry_size_t jerry_port_path_base (const jerry_char_t *path_p);
225+
jerry_size_t jerry_port_get_cwd (jerry_char_t *buffer_p, jerry_size_t buffer_size);
234226

235227
/**
236228
* Open a source file and read the content into a buffer.

‎jerry-core/include/jerryscript-types.h

+16-1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,15 @@ typedef uint32_t jerry_length_t;
153153
*/
154154
typedef uint32_t jerry_value_t;
155155

156+
/**
157+
* Description of a JerryScript string for arguments passing
158+
*/
159+
typedef struct
160+
{
161+
const jerry_char_t *ptr; /**< pointer to the zero-terminated ASCII/UTF-8/CESU-8 string */
162+
jerry_size_t size; /**< size of the string, excluding '\0' terminator */
163+
} jerry_string_t;
164+
156165
/**
157166
* Option bits for jerry_parse_options_t.
158167
*/
@@ -856,10 +865,16 @@ typedef void (*jerry_arraybuffer_free_cb_t) (jerry_arraybuffer_type_t buffer_typ
856865
void *arraybuffer_user_p,
857866
void *user_p);
858867

868+
/**
869+
* Helper to to ensure str is a string literal
870+
*/
871+
#define JERRY_ZSTR_ENSURE_STRING_LITERAL(str) str ""
872+
859873
/**
860874
* Helper to expand string literal to [string pointer, string size] argument pair.
861875
*/
862-
#define JERRY_ZSTR_ARG(str) ((const jerry_char_t *) (str)), ((jerry_size_t) (sizeof (str) - 1))
876+
#define JERRY_ZSTR_ARG(str) \
877+
((const jerry_char_t *) (JERRY_ZSTR_ENSURE_STRING_LITERAL (str))), ((jerry_size_t) (sizeof (str) - 1))
863878

864879
/**
865880
* @}

‎jerry-ext/include/jerryscript-ext/sources.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020

2121
JERRY_C_API_BEGIN
2222

23-
jerry_value_t jerryx_source_parse_script (const char* path);
24-
jerry_value_t jerryx_source_exec_script (const char* path);
25-
jerry_value_t jerryx_source_exec_module (const char* path);
26-
jerry_value_t jerryx_source_exec_snapshot (const char* path, size_t function_index);
23+
jerry_value_t jerryx_source_parse_script (const jerry_string_t *path);
24+
jerry_value_t jerryx_source_exec_script (const jerry_string_t *path);
25+
jerry_value_t jerryx_source_exec_module (const jerry_string_t *path);
26+
jerry_value_t jerryx_source_exec_snapshot (const jerry_string_t *path, size_t function_index);
2727
jerry_value_t jerryx_source_exec_stdin (void);
2828

2929
JERRY_C_API_END

‎jerry-ext/util/sources.c

+10-12
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727
#include "jerryscript-ext/print.h"
2828

2929
jerry_value_t
30-
jerryx_source_parse_script (const char *path_p)
30+
jerryx_source_parse_script (const jerry_string_t *path_p)
3131
{
3232
jerry_size_t source_size;
33-
jerry_char_t *source_p = jerry_port_source_read (path_p, &source_size);
33+
jerry_char_t *source_p = jerry_port_source_read ((const char *) path_p->ptr, &source_size);
3434

3535
if (source_p == NULL)
3636
{
37-
jerry_log (JERRY_LOG_LEVEL_ERROR, "Failed to open file: %s\n", path_p);
37+
jerry_log (JERRY_LOG_LEVEL_ERROR, "Failed to open file: %.*s\n", path_p->size, path_p->ptr);
3838
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Source file not found");
3939
}
4040

@@ -46,8 +46,7 @@ jerryx_source_parse_script (const char *path_p)
4646

4747
jerry_parse_options_t parse_options;
4848
parse_options.options = JERRY_PARSE_HAS_SOURCE_NAME;
49-
parse_options.source_name =
50-
jerry_string ((const jerry_char_t *) path_p, (jerry_size_t) strlen (path_p), JERRY_ENCODING_UTF8);
49+
parse_options.source_name = jerry_string (path_p->ptr, path_p->size, JERRY_ENCODING_UTF8);
5150

5251
jerry_value_t result = jerry_parse (source_p, source_size, &parse_options);
5352

@@ -58,7 +57,7 @@ jerryx_source_parse_script (const char *path_p)
5857
} /* jerryx_source_parse_script */
5958

6059
jerry_value_t
61-
jerryx_source_exec_script (const char *path_p)
60+
jerryx_source_exec_script (const jerry_string_t *path_p)
6261
{
6362
jerry_value_t result = jerryx_source_parse_script (path_p);
6463

@@ -73,10 +72,9 @@ jerryx_source_exec_script (const char *path_p)
7372
} /* jerryx_source_exec_script */
7473

7574
jerry_value_t
76-
jerryx_source_exec_module (const char *path_p)
75+
jerryx_source_exec_module (const jerry_string_t *path_p)
7776
{
78-
jerry_value_t specifier =
79-
jerry_string ((const jerry_char_t *) path_p, (jerry_size_t) strlen (path_p), JERRY_ENCODING_UTF8);
77+
jerry_value_t specifier = jerry_string (path_p->ptr, path_p->size, JERRY_ENCODING_UTF8);
8078
jerry_value_t referrer = jerry_undefined ();
8179

8280
jerry_value_t module = jerry_module_resolve (specifier, referrer, NULL);
@@ -110,14 +108,14 @@ jerryx_source_exec_module (const char *path_p)
110108
} /* jerryx_source_exec_module */
111109

112110
jerry_value_t
113-
jerryx_source_exec_snapshot (const char *path_p, size_t function_index)
111+
jerryx_source_exec_snapshot (const jerry_string_t *path_p, size_t function_index)
114112
{
115113
jerry_size_t source_size;
116-
jerry_char_t *source_p = jerry_port_source_read (path_p, &source_size);
114+
jerry_char_t *source_p = jerry_port_source_read ((const char *) path_p->ptr, &source_size);
117115

118116
if (source_p == NULL)
119117
{
120-
jerry_log (JERRY_LOG_LEVEL_ERROR, "Failed to open file: %s\n", path_p);
118+
jerry_log (JERRY_LOG_LEVEL_ERROR, "Failed to open file: %.*s\n", path_p->size, path_p->ptr);
121119
return jerry_throw_sz (JERRY_ERROR_SYNTAX, "Snapshot file not found");
122120
}
123121

‎jerry-main/main-desktop.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,18 @@ main (int argc, char **argv)
130130
{
131131
main_source_t *source_file_p = sources_p + source_index;
132132
const char *file_path_p = argv[source_file_p->path_index];
133+
jerry_string_t file_path = { (const jerry_char_t *) file_path_p, (jerry_size_t) strlen (file_path_p) };
133134

134135
switch (source_file_p->type)
135136
{
136137
case SOURCE_MODULE:
137138
{
138-
result = jerryx_source_exec_module (file_path_p);
139+
result = jerryx_source_exec_module (&file_path);
139140
break;
140141
}
141142
case SOURCE_SNAPSHOT:
142143
{
143-
result = jerryx_source_exec_snapshot (file_path_p, source_file_p->snapshot_index);
144+
result = jerryx_source_exec_snapshot (&file_path, source_file_p->snapshot_index);
144145
break;
145146
}
146147
default:
@@ -149,11 +150,11 @@ main (int argc, char **argv)
149150

150151
if ((arguments.option_flags & OPT_FLAG_PARSE_ONLY) != 0)
151152
{
152-
result = jerryx_source_parse_script (file_path_p);
153+
result = jerryx_source_parse_script (&file_path);
153154
}
154155
else
155156
{
156-
result = jerryx_source_exec_script (file_path_p);
157+
result = jerryx_source_exec_script (&file_path);
157158
}
158159

159160
break;

‎jerry-port/common/jerry-port-fs.c

+22-45
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#ifndef S_ISDIR
2626
#define S_ISDIR(mode) (((mode) &S_IFMT) == S_IFDIR)
2727
#endif /* !defined(S_ISDIR) */
28-
#endif /* __GLIBC__ */
28+
#endif /* defined(__GLIBC__) || defined(_WIN32) */
2929

3030
/**
3131
* Determines the size of the given file.
@@ -59,7 +59,7 @@ jerry_port_source_read (const char *file_name_p, /**< file name */
5959
{
6060
return NULL;
6161
}
62-
#endif /* __GLIBC__ */
62+
#endif /* defined(__GLIBC__) || defined(_WIN32) */
6363

6464
FILE *file_p = fopen (file_name_p, "rb");
6565

@@ -101,62 +101,39 @@ jerry_port_source_free (uint8_t *buffer_p) /**< buffer to free */
101101
free (buffer_p);
102102
} /* jerry_port_source_free */
103103

104+
#if !defined(_WIN32)
105+
106+
jerry_path_style_t
107+
jerry_port_path_style (void)
108+
{
109+
return JERRY_PATH_STYLE_POSIX;
110+
} /* jerry_port_path_style */
111+
112+
#endif /* !defined(_WIN32) */
113+
104114
/**
105115
* These functions provide generic implementation for paths and are only enabled when the compiler support weak symbols,
106116
* and we are not building for a platform that has platform specific versions.
107117
*/
108118
#if defined(JERRY_WEAK_SYMBOL_SUPPORT) && !(defined(__unix__) || defined(__APPLE__) || defined(_WIN32))
109119

110120
/**
111-
* Normalize a file path.
112-
*
113-
* @return a newly allocated buffer with the normalized path if the operation is successful,
114-
* NULL otherwise
121+
* Default to `/`
115122
*/
116-
jerry_char_t *JERRY_ATTR_WEAK
117-
jerry_port_path_normalize (const jerry_char_t *path_p, /**< input path */
118-
jerry_size_t path_size) /**< size of the path */
123+
jerry_size_t JERRY_ATTR_WEAK
124+
jerry_port_get_cwd (jerry_char_t *buffer_p, jerry_size_t buffer_size)
119125
{
120-
jerry_char_t *buffer_p = (jerry_char_t *) malloc (path_size + 1);
121-
122126
if (buffer_p == NULL)
123127
{
124-
return NULL;
128+
return 1;
125129
}
126-
127-
/* Also copy terminating zero byte. */
128-
memcpy (buffer_p, path_p, path_size + 1);
129-
130-
return buffer_p;
131-
} /* jerry_port_path_normalize */
132-
133-
/**
134-
* Free a path buffer returned by jerry_port_path_normalize.
135-
*
136-
* @param path_p: the path to free
137-
*/
138-
void JERRY_ATTR_WEAK
139-
jerry_port_path_free (jerry_char_t *path_p)
140-
{
141-
free (path_p);
142-
} /* jerry_port_path_free */
143-
144-
/**
145-
* Computes the end of the directory part of a path.
146-
*
147-
* @return end of the directory part of a path.
148-
*/
149-
jerry_size_t JERRY_ATTR_WEAK
150-
jerry_port_path_base (const jerry_char_t *path_p) /**< path */
151-
{
152-
const jerry_char_t *basename_p = (jerry_char_t *) strrchr ((char *) path_p, '/') + 1;
153-
154-
if (basename_p == NULL)
130+
if (buffer_size == 2)
155131
{
156-
return 0;
132+
path_p[0] = '/';
133+
path_p[1] = '\0';
134+
return 1;
157135
}
158-
159-
return (jerry_size_t) (basename_p - path_p);
160-
} /* jerry_port_get_directory_end */
136+
return 0;
137+
} /* jerry_port_get_cwd */
161138

162139
#endif /* defined(JERRY_WEAK_SYMBOL_SUPPORT) && !(defined(__unix__) || defined(__APPLE__) || defined(_WIN32)) */

‎jerry-port/unix/jerry-port-unix-fs.c

+35-38
Original file line numberDiff line numberDiff line change
@@ -19,45 +19,42 @@
1919

2020
#include <stdlib.h>
2121
#include <string.h>
22+
#include <unistd.h>
2223

23-
/**
24-
* Normalize a file path using realpath.
25-
*
26-
* @param path_p: input path
27-
* @param path_size: input path size
28-
*
29-
* @return a newly allocated buffer with the normalized path if the operation is successful,
30-
* NULL otherwise
31-
*/
32-
jerry_char_t *
33-
jerry_port_path_normalize (const jerry_char_t *path_p, /**< input path */
34-
jerry_size_t path_size) /**< size of the path */
35-
{
36-
(void) path_size;
37-
38-
return (jerry_char_t *) realpath ((char *) path_p, NULL);
39-
} /* jerry_port_path_normalize */
40-
41-
/**
42-
* Free a path buffer returned by jerry_port_path_normalize.
43-
*/
44-
void
45-
jerry_port_path_free (jerry_char_t *path_p)
46-
{
47-
free (path_p);
48-
} /* jerry_port_path_free */
49-
50-
/**
51-
* Computes the end of the directory part of a path.
52-
*
53-
* @return end of the directory part of a path.
54-
*/
55-
jerry_size_t JERRY_ATTR_WEAK
56-
jerry_port_path_base (const jerry_char_t *path_p) /**< path */
24+
jerry_size_t
25+
jerry_port_get_cwd (jerry_char_t *buffer_p, jerry_size_t buffer_size)
5726
{
58-
const jerry_char_t *basename_p = (jerry_char_t *) strrchr ((char *) path_p, '/') + 1;
59-
60-
return (jerry_size_t) (basename_p - path_p);
61-
} /* jerry_port_get_directory_end */
27+
if (buffer_p == NULL)
28+
{
29+
jerry_size_t size = 260;
30+
char *buf = NULL;
31+
char *ptr = NULL;
32+
for (; ptr == NULL; size *= 2)
33+
{
34+
if ((buf = realloc (buf, size)) == NULL)
35+
{
36+
break;
37+
}
38+
ptr = getcwd (buf, size);
39+
if (ptr == NULL && errno != ERANGE)
40+
{
41+
break;
42+
}
43+
}
44+
size = ptr ? (jerry_size_t) strlen (ptr) : 0;
45+
if (buf)
46+
free (buf);
47+
return size;
48+
}
49+
50+
if (getcwd ((char *) buffer_p, buffer_size) != NULL)
51+
{
52+
if ((strlen ((char *) buffer_p) + 1) == buffer_size)
53+
{
54+
return buffer_size - 1;
55+
}
56+
}
57+
return 0;
58+
} /* jerry_port_get_cwd */
6259

6360
#endif /* defined(__unix__) || defined(__APPLE__) */

‎jerry-port/win/jerry-port-win-fs.c

+32-38
Original file line numberDiff line numberDiff line change
@@ -17,56 +17,50 @@
1717

1818
#if defined(_WIN32)
1919

20+
#include <direct.h>
2021
#include <stdlib.h>
2122
#include <string.h>
2223

23-
/**
24-
* Normalize a file path.
25-
*
26-
* @return a newly allocated buffer with the normalized path if the operation is successful,
27-
* NULL otherwise
28-
*/
29-
jerry_char_t *
30-
jerry_port_path_normalize (const jerry_char_t *path_p, /**< input path */
31-
jerry_size_t path_size) /**< size of the path */
32-
{
33-
(void) path_size;
34-
35-
return (jerry_char_t *) _fullpath (NULL, path_p, _MAX_PATH);
36-
} /* jerry_port_path_normalize */
37-
38-
/**
39-
* Free a path buffer returned by jerry_port_path_normalize.
40-
*/
41-
void
42-
jerry_port_path_free (jerry_char_t *path_p)
24+
jerry_path_style_t
25+
jerry_port_path_style (void)
4326
{
44-
free (path_p);
45-
} /* jerry_port_path_free */
27+
return JERRY_PATH_STYLE_WINDOWS;
28+
} /* jerry_port_path_style */
4629

47-
/**
48-
* Get the end of the directory part of the input path.
49-
*
50-
* @param path_p: input zero-terminated path string
51-
*
52-
* @return offset of the directory end in the input path string
53-
*/
5430
jerry_size_t
55-
jerry_port_path_base (const jerry_char_t *path_p)
31+
jerry_port_get_cwd (jerry_char_t *buffer_p, jerry_size_t buffer_size)
5632
{
57-
const jerry_char_t *end_p = path_p + strlen ((const char *) path_p);
58-
59-
while (end_p > path_p)
33+
if (buffer_p == NULL)
6034
{
61-
if (end_p[-1] == '/' || end_p[-1] == '\\')
35+
jerry_size_t size = _MAX_PATH;
36+
char *buf = NULL;
37+
char *ptr = NULL;
38+
for (; ptr == NULL; size *= 2)
6239
{
63-
return (jerry_size_t) (end_p - path_p);
40+
if ((buf = realloc (buf, size)) == NULL)
41+
{
42+
break;
43+
}
44+
ptr = getcwd (buf, size);
45+
if (ptr == NULL && errno != ERANGE)
46+
{
47+
break;
48+
}
6449
}
65-
66-
end_p--;
50+
size = ptr ? (jerry_size_t) strlen (ptr) : 0;
51+
if (buf)
52+
free (buf);
53+
return size;
6754
}
6855

56+
if (getcwd ((char *) buffer_p, buffer_size) != NULL)
57+
{
58+
if ((strlen ((char *) buffer_p) + 1) == buffer_size)
59+
{
60+
return buffer_size - 1;
61+
}
62+
}
6963
return 0;
70-
} /* jerry_port_path_base */
64+
} /* jerry_port_get_cwd */
7165

7266
#endif /* defined(_WIN32) */

0 commit comments

Comments
 (0)
Please sign in to comment.