safec  2.1
Safe C Library - ISO TR24731 Bounds Checking Interface
strcpyfldin_s.c
Go to the documentation of this file.
1 /*------------------------------------------------------------------
2  * strcpyfldin_s.c
3  *
4  * November 2008, Bo Berry
5  *
6  * Copyright (c) 2008-2011 by Cisco Systems, Inc
7  * All rights reserved.
8  *
9  * Permission is hereby granted, free of charge, to any person
10  * obtaining a copy of this software and associated documentation
11  * files (the "Software"), to deal in the Software without
12  * restriction, including without limitation the rights to use,
13  * copy, modify, merge, publish, distribute, sublicense, and/or
14  * sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following
16  * conditions:
17  *
18  * The above copyright notice and this permission notice shall be
19  * included in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  * OTHER DEALINGS IN THE SOFTWARE.
29  *------------------------------------------------------------------
30  */
31 
32 #include "safeclib_private.h"
33 #include "safe_str_constraint.h"
34 #include "safe_str_lib.h"
35 
36 
77 errno_t
78 strcpyfldin_s (char *dest, rsize_t dmax, const char *src, rsize_t slen)
79 {
80  rsize_t orig_dmax;
81  char *orig_dest;
82  const char *overlap_bumper;
83 
84  if (dest == NULL) {
85  invoke_safe_str_constraint_handler("strcpyfldin_s: dest is null",
86  NULL, ESNULLP);
87  return (ESNULLP);
88  }
89 
90  if (dmax == 0) {
91  invoke_safe_str_constraint_handler("strcpyfldin_s: dmax is 0",
92  NULL, ESZEROL);
93  return (ESZEROL);
94  }
95 
96  if (dmax > RSIZE_MAX_STR) {
97  invoke_safe_str_constraint_handler("strcpyfldin_s: dmax exceeds max",
98  NULL, ESLEMAX);
99  return (ESLEMAX);
100  }
101 
102  if (src == NULL) {
103  /* null string to clear data */
104  while (dmax) { *dest = '\0'; dmax--; dest++; }
105 
106  invoke_safe_str_constraint_handler("strcpyfldin_s: src is null",
107  NULL, ESNULLP);
108  return (ESNULLP);
109  }
110 
111  if (slen == 0) {
112  /* null string to clear data */
113  while (dmax) { *dest = '\0'; dmax--; dest++; }
114 
115  invoke_safe_str_constraint_handler("strcpyfldin_s: slen is 0",
116  NULL, ESZEROL);
117  return (ESZEROL);
118  }
119 
120  if (slen > dmax) {
121  /* null string to clear data */
122  while (dmax) { *dest = '\0'; dmax--; dest++; }
123 
124  invoke_safe_str_constraint_handler("strcpyfldin_s: slen exceeds max",
125  NULL, ESNOSPC);
126  return (ESNOSPC);
127  }
128 
129 
130  /* hold base of dest in case src was not copied */
131  orig_dmax = dmax;
132  orig_dest = dest;
133 
134  if (dest < src) {
135  overlap_bumper = src;
136 
137  while (dmax > 0 && *src) {
138 
139  if (dest == overlap_bumper) {
140  dmax = orig_dmax;
141  dest = orig_dest;
142 
143  /* null string to eliminate partial copy */
144  while (dmax) { *dest = '\0'; dmax--; dest++; }
145 
147  "strcpyfldin_s: overlapping objects",
148  NULL, ESOVRLP);
149  return (ESOVRLP);
150  }
151 
152  dmax--;
153  *dest++ = *src++;
154  }
155 
156  } else {
157  overlap_bumper = dest;
158 
159  while (dmax > 0 && *src) {
160 
161  if (src == overlap_bumper) {
162  dmax = orig_dmax;
163  dest = orig_dest;
164 
165  /* null string to eliminate partial copy */
166  while (dmax) { *dest = '\0'; dmax--; dest++; }
167 
169  "strcpyfldin_s: overlapping objects",
170  NULL, ESOVRLP);
171  return (ESOVRLP);
172  }
173 
174  dmax--;
175  *dest++ = *src++;
176  }
177  }
178 
179  /*
180  * finish filling in the field with nulls if there is slack space
181  */
182  while (dmax) { *dest = '\0'; dmax--; dest++; }
183 
184  return (EOK);
185 }
errno_t strcpyfldin_s(char *dest, rsize_t dmax, const char *src, rsize_t slen)
The strcpyfldin_s function copies at most slen characters from the null terminated string pointed to ...
Definition: strcpyfldin_s.c:78
void invoke_safe_str_constraint_handler(const char *msg, void *ptr, errno_t error)
Invokes the currently set constraint handler or the default.