Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersSafeStrings.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* This helpers are used to interact safely with buffers to not overflow.
4
5 Currently this is used for char and wchar_t string buffers and shared
6 between onefile bootstrap for Windows, plugins and Nuitka core, but
7 should not use any Python level functionality.
8*/
9
10// This file is included from another C file, help IDEs to still parse it on
11// its own.
12#ifdef __IDE_ONLY__
13#if defined(_WIN32)
14#include <windows.h>
15#endif
16#include <stdbool.h>
17#include <stdio.h>
18#endif
19
20#include "nuitka/safe_string_ops.h"
21
22#include <ctype.h>
23#include <wctype.h>
24
25void copyStringSafe(char *buffer, char const *source, size_t buffer_size) {
26 if (strlen(source) >= buffer_size) {
27 abort();
28 }
29
30 if (buffer != source) {
31 strcpy(buffer, source);
32 }
33}
34
35void copyStringSafeN(char *buffer, char const *source, size_t n, size_t buffer_size) {
36 if (n >= buffer_size - 1) {
37 abort();
38 }
39 strncpy(buffer, source, n);
40 buffer[n] = 0;
41}
42
43void copyStringSafeW(wchar_t *buffer, wchar_t const *source, size_t buffer_size) {
44 while (*source != 0) {
45 if (buffer_size < 1) {
46 abort();
47 }
48
49 *buffer++ = *source++;
50 buffer_size -= 1;
51 }
52
53 *buffer = 0;
54}
55
56void appendStringSafe(char *target, char const *source, size_t buffer_size) {
57 if (strlen(source) + strlen(target) >= buffer_size) {
58 abort();
59 }
60 strcat(target, source);
61}
62
63void appendCharSafe(char *target, char c, size_t buffer_size) {
64 char source[2] = {c, 0};
65
66 appendStringSafe(target, source, buffer_size);
67}
68
69void appendWStringSafeW(wchar_t *target, wchar_t const *source, size_t buffer_size) {
70 if (unlikely(source == NULL)) {
71 abort();
72 }
73
74 while (*target != 0) {
75 target++;
76 buffer_size -= 1;
77 }
78
79 while (*source != 0) {
80 if (unlikely(buffer_size < 1)) {
81 abort();
82 }
83
84 *target++ = *source++;
85 buffer_size -= 1;
86 }
87
88 *target = 0;
89}
90
91void appendWCharSafeW(wchar_t *target, wchar_t c, size_t buffer_size) {
92 while (*target != 0) {
93 target++;
94 buffer_size -= 1;
95 }
96
97 if (buffer_size < 1) {
98 abort();
99 }
100
101 *target++ = c;
102 *target = 0;
103}
104
105void appendCharSafeW(wchar_t *target, char c, size_t buffer_size) {
106 char buffer_c[2] = {c, 0};
107 wchar_t wide_buffer_c[2];
108
109 size_t res = mbstowcs(wide_buffer_c, buffer_c, 2);
110 if (res != 1) {
111 abort();
112 }
113
114 appendWCharSafeW(target, wide_buffer_c[0], buffer_size);
115}
116
117void appendStringSafeW(wchar_t *target, char const *source, size_t buffer_size) {
118 while (*target != 0) {
119 target++;
120 buffer_size -= 1;
121 }
122
123 while (*source != 0) {
124 appendCharSafeW(target, *source, buffer_size);
125 target++;
126 source++;
127 buffer_size -= 1;
128 }
129}
130
131void checkWStringNumber(wchar_t const *value) {
132 if (unlikely(value == NULL || *value == 0)) {
133 abort();
134 }
135
136 while (*value) {
137 if (!iswdigit(*value)) {
138 abort();
139 }
140
141 value++;
142 }
143}
144
145void checkStringNumber(char const *value) {
146 if (unlikely(value == NULL || *value == 0)) {
147 abort();
148 }
149
150 while (*value) {
151 if (!isdigit(*value)) {
152 abort();
153 }
154
155 value++;
156 }
157}
158
159void printOSErrorMessage(char const *message, error_code_t error_code) {
160#if defined(_WIN32)
161 LPCTSTR err_buffer;
162
163 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
164 error_code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPTSTR)&err_buffer, 0, NULL);
165
166 fprintf(stderr, "%s ([Error " ERROR_CODE_FORMAT_STR "] %s)\n", message, error_code, err_buffer);
167#else
168 fprintf(stderr, "%s: %s\n", message, strerror(error_code));
169#endif
170}
171
172// Part of "Nuitka", an optimizing Python compiler that is compatible and
173// integrates with CPython, but also works on its own.
174//
175// Licensed under the Apache License, Version 2.0 (the "License");
176// you may not use this file except in compliance with the License.
177// You may obtain a copy of the License at
178//
179// http://www.apache.org/licenses/LICENSE-2.0
180//
181// Unless required by applicable law or agreed to in writing, software
182// distributed under the License is distributed on an "AS IS" BASIS,
183// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
184// See the License for the specific language governing permissions and
185// limitations under the License.