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+ */
141#include <ctype.h>
242#include <stdio.h>
343#include <stdlib.h>
1858 * Returns a newly allocated string. Caller must free() it.
1959 */
2060char * 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" );
2262 if (fp == NULL ) {
2363 fprintf (stderr , "Failed to open pyenv.cfg file!\n" );
2464 exit (1 );
2565 }
2666
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 ;
3071
31- while (fgets ( current_line , sizeof ( current_line ) , fp )) {
72+ while (getline ( & current_line , & current_line_size , fp ) != -1 ) {
3273 char * p = current_line ;
3374
3475 while (isspace ((unsigned char ) * p )) p ++ ;
@@ -38,25 +79,40 @@ char *get_pyenvcfg_command(const char *pyenv_cfg_path) {
3879
3980 // Skip spaces and '='
4081 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+ }
4290 while (isspace ((unsigned char ) * p )) p ++ ;
4391 if (* p == '\"' ) {
4492 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' ) ) {
4694 * -- end = '\0' ;
4795 }
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 );
50100 exit (1 );
51101 }
52102 p ++ ;
53103 end [-1 ] = '\0' ;
54104 }
55105
106+ char * result = strdup (p );
107+ free (current_line );
56108 fclose (fp );
57- return strdup (p );
109+ return result ;
110+
58111 }
59112 }
113+ free (current_line );
114+ fprintf (stderr , "venvlauncher_command not found in pyenv.cfg file" );
115+ exit (1 );
60116}
61117
62118void split_venv_command_into_args (char * venv_command , char * result []) {
@@ -144,3 +200,4 @@ int main(int argc, char *argv[]) {
144200 perror ("execv failed" ); // only runs if execv fails
145201 return 1 ;
146202}
203+
0 commit comments