1
+ /*
2
+ * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
+ *
5
+ * The Universal Permissive License (UPL), Version 1.0
6
+ *
7
+ * Subject to the condition set forth below, permission is hereby granted to any
8
+ * person obtaining a copy of this software, associated documentation and/or
9
+ * data (collectively the "Software"), free of charge and under any and all
10
+ * copyright rights in the Software, and any and all patent rights owned or
11
+ * freely licensable by each licensor hereunder covering either (i) the
12
+ * unmodified Software as contributed to or provided by such licensor, or (ii)
13
+ * the Larger Works (as defined below), to deal in both
14
+ *
15
+ * (a) the Software, and
16
+ *
17
+ * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18
+ * one is included with the Software each a "Larger Work" to which the Software
19
+ * is contributed by such licensors),
20
+ *
21
+ * without restriction, including without limitation the rights to copy, create
22
+ * derivative works of, display, perform, and distribute the Software and make,
23
+ * use, sell, offer for sale, import, export, have made, and have sold the
24
+ * Software and the Larger Work(s), and to sublicense the foregoing rights on
25
+ * either these or other terms.
26
+ *
27
+ * This license is subject to the following condition:
28
+ *
29
+ * The above copyright notice and either this complete permission notice or at a
30
+ * minimum a reference to the UPL must be included in all copies or substantial
31
+ * portions of the Software.
32
+ *
33
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39
+ * SOFTWARE.
40
+ */
1
41
#include <ctype.h>
2
42
#include <stdio.h>
3
43
#include <stdlib.h>
18
58
* Returns a newly allocated string. Caller must free() it.
19
59
*/
20
60
char * get_pyenvcfg_command (const char * pyenv_cfg_path ) {
21
- const FILE * fp = fopen (pyenv_cfg_path , "r" );
61
+ FILE * fp = fopen (pyenv_cfg_path , "r" );
22
62
if (fp == NULL ) {
23
63
fprintf (stderr , "Failed to open pyenv.cfg file!\n" );
24
64
exit (1 );
25
65
}
26
66
27
- char current_line [MAX_LINE ];
28
- const char * key = "venvlauncher_command" ;
29
- size_t key_len = strlen (key );
67
+ char * current_line = NULL ;
68
+ size_t current_line_size = 0 ;
69
+ const char key [] = "venvlauncher_command" ;
70
+ size_t key_len = sizeof (key ) - 1 ;
30
71
31
- while (fgets ( current_line , sizeof ( current_line ) , fp )) {
72
+ while (getline ( & current_line , & current_line_size , fp ) != -1 ) {
32
73
char * p = current_line ;
33
74
34
75
while (isspace ((unsigned char ) * p )) p ++ ;
@@ -38,25 +79,40 @@ char *get_pyenvcfg_command(const char *pyenv_cfg_path) {
38
79
39
80
// Skip spaces and '='
40
81
while (isspace ((unsigned char ) * p )) p ++ ;
41
- if (* p == '=' ) p ++ ;
82
+ if (* p == '=' ) {
83
+ p ++ ;
84
+ } else {
85
+ fprintf (stderr , "venv command is not in correct format. Expected '=' after the venvlauncher_command" );
86
+ free (current_line );
87
+ fclose (fp );
88
+ exit (1 );
89
+ }
42
90
while (isspace ((unsigned char ) * p )) p ++ ;
43
91
if (* p == '\"' ) {
44
92
char * end = p + strlen (p );
45
- while (isspace ((unsigned char ) end [-1 ]) || end [-1 ] == '\n' ) {
93
+ while (end > p && ( isspace ((unsigned char ) end [-1 ]) || end [-1 ] == '\n' ) ) {
46
94
* -- end = '\0' ;
47
95
}
48
- if (end [-1 ] != '\"' ) {
49
- fprintf (stderr , "venv command is not in correct format!" );
96
+ if (end <= p + 1 || end [-1 ] != '\"' ) {
97
+ fprintf (stderr , "venv command is not in correct format" );
98
+ free (current_line );
99
+ fclose (fp );
50
100
exit (1 );
51
101
}
52
102
p ++ ;
53
103
end [-1 ] = '\0' ;
54
104
}
55
105
106
+ char * result = strdup (p );
107
+ free (current_line );
56
108
fclose (fp );
57
- return strdup (p );
109
+ return result ;
110
+
58
111
}
59
112
}
113
+ free (current_line );
114
+ fprintf (stderr , "venvlauncher_command not found in pyenv.cfg file" );
115
+ exit (1 );
60
116
}
61
117
62
118
void split_venv_command_into_args (char * venv_command , char * result []) {
@@ -144,3 +200,4 @@ int main(int argc, char *argv[]) {
144
200
perror ("execv failed" ); // only runs if execv fails
145
201
return 1 ;
146
202
}
203
+
0 commit comments