Coverage Report

Created: 2022-10-31 07:00

/src/cups/cups/ppd-attr.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * PPD model-specific attribute routines for CUPS.
3
 *
4
 * Copyright 2007-2015 by Apple Inc.
5
 * Copyright 1997-2006 by Easy Software Products.
6
 *
7
 * These coded instructions, statements, and computer programs are the
8
 * property of Apple Inc. and are protected by Federal copyright
9
 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
10
 * which should have been included with this file.  If this file is
11
 * missing or damaged, see the license at "http://www.cups.org/".
12
 */
13
14
/*
15
 * Include necessary headers...
16
 */
17
18
#include "cups-private.h"
19
#include "ppd-private.h"
20
21
22
/*
23
 * 'ppdFindAttr()' - Find the first matching attribute.
24
 *
25
 * @since CUPS 1.1.19/macOS 10.3@
26
 */
27
28
ppd_attr_t *        /* O - Attribute or @code NULL@ if not found */
29
ppdFindAttr(ppd_file_t *ppd,    /* I - PPD file data */
30
            const char *name,   /* I - Attribute name */
31
            const char *spec)   /* I - Specifier string or @code NULL@ */
32
0
{
33
0
  ppd_attr_t  key,      /* Search key */
34
0
    *attr;      /* Current attribute */
35
36
37
0
  DEBUG_printf(("2ppdFindAttr(ppd=%p, name=\"%s\", spec=\"%s\")", ppd, name,
38
0
                spec));
39
40
 /*
41
  * Range check input...
42
  */
43
44
0
  if (!ppd || !name || ppd->num_attrs == 0)
45
0
    return (NULL);
46
47
 /*
48
  * Search for a matching attribute...
49
  */
50
51
0
  memset(&key, 0, sizeof(key));
52
0
  strlcpy(key.name, name, sizeof(key.name));
53
54
 /*
55
  * Return the first matching attribute, if any...
56
  */
57
58
0
  if ((attr = (ppd_attr_t *)cupsArrayFind(ppd->sorted_attrs, &key)) != NULL)
59
0
  {
60
0
    if (spec)
61
0
    {
62
     /*
63
      * Loop until we find the first matching attribute for "spec"...
64
      */
65
66
0
      while (attr && _cups_strcasecmp(spec, attr->spec))
67
0
      {
68
0
        if ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL &&
69
0
      _cups_strcasecmp(attr->name, name))
70
0
    attr = NULL;
71
0
      }
72
0
    }
73
0
  }
74
75
0
  return (attr);
76
0
}
77
78
79
/*
80
 * 'ppdFindNextAttr()' - Find the next matching attribute.
81
 *
82
 * @since CUPS 1.1.19/macOS 10.3@
83
 */
84
85
ppd_attr_t *        /* O - Attribute or @code NULL@ if not found */
86
ppdFindNextAttr(ppd_file_t *ppd,  /* I - PPD file data */
87
                const char *name, /* I - Attribute name */
88
    const char *spec) /* I - Specifier string or @code NULL@ */
89
0
{
90
0
  ppd_attr_t  *attr;      /* Current attribute */
91
92
93
 /*
94
  * Range check input...
95
  */
96
97
0
  if (!ppd || !name || ppd->num_attrs == 0)
98
0
    return (NULL);
99
100
 /*
101
  * See if there are more attributes to return...
102
  */
103
104
0
  while ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL)
105
0
  {
106
   /*
107
    * Check the next attribute to see if it is a match...
108
    */
109
110
0
    if (_cups_strcasecmp(attr->name, name))
111
0
    {
112
     /*
113
      * Nope, reset the current pointer to the end of the array...
114
      */
115
116
0
      cupsArrayIndex(ppd->sorted_attrs, cupsArrayCount(ppd->sorted_attrs));
117
118
0
      return (NULL);
119
0
    }
120
121
0
    if (!spec || !_cups_strcasecmp(attr->spec, spec))
122
0
      break;
123
0
  }
124
125
 /*
126
  * Return the next attribute's value...
127
  */
128
129
0
  return (attr);
130
0
}
131
132
133
/*
134
 * '_ppdNormalizeMakeAndModel()' - Normalize a product/make-and-model string.
135
 *
136
 * This function tries to undo the mistakes made by many printer manufacturers
137
 * to produce a clean make-and-model string we can use.
138
 */
139
140
char *          /* O - Normalized make-and-model string or NULL on error */
141
_ppdNormalizeMakeAndModel(
142
    const char *make_and_model,   /* I - Original make-and-model string */
143
    char       *buffer,     /* I - String buffer */
144
    size_t     bufsize)     /* I - Size of string buffer */
145
0
{
146
0
  char  *bufptr;      /* Pointer into buffer */
147
148
149
0
  if (!make_and_model || !buffer || bufsize < 1)
150
0
  {
151
0
    if (buffer)
152
0
      *buffer = '\0';
153
154
0
    return (NULL);
155
0
  }
156
157
 /*
158
  * Skip leading whitespace...
159
  */
160
161
0
  while (_cups_isspace(*make_and_model))
162
0
    make_and_model ++;
163
164
 /*
165
  * Remove parenthesis and add manufacturers as needed...
166
  */
167
168
0
  if (make_and_model[0] == '(')
169
0
  {
170
0
    strlcpy(buffer, make_and_model + 1, bufsize);
171
172
0
    if ((bufptr = strrchr(buffer, ')')) != NULL)
173
0
      *bufptr = '\0';
174
0
  }
175
0
  else if (!_cups_strncasecmp(make_and_model, "XPrint", 6))
176
0
  {
177
   /*
178
    * Xerox XPrint...
179
    */
180
181
0
    snprintf(buffer, bufsize, "Xerox %s", make_and_model);
182
0
  }
183
0
  else if (!_cups_strncasecmp(make_and_model, "Eastman", 7))
184
0
  {
185
   /*
186
    * Kodak...
187
    */
188
189
0
    snprintf(buffer, bufsize, "Kodak %s", make_and_model + 7);
190
0
  }
191
0
  else if (!_cups_strncasecmp(make_and_model, "laserwriter", 11))
192
0
  {
193
   /*
194
    * Apple LaserWriter...
195
    */
196
197
0
    snprintf(buffer, bufsize, "Apple LaserWriter%s", make_and_model + 11);
198
0
  }
199
0
  else if (!_cups_strncasecmp(make_and_model, "colorpoint", 10))
200
0
  {
201
   /*
202
    * Seiko...
203
    */
204
205
0
    snprintf(buffer, bufsize, "Seiko %s", make_and_model);
206
0
  }
207
0
  else if (!_cups_strncasecmp(make_and_model, "fiery", 5))
208
0
  {
209
   /*
210
    * EFI...
211
    */
212
213
0
    snprintf(buffer, bufsize, "EFI %s", make_and_model);
214
0
  }
215
0
  else if (!_cups_strncasecmp(make_and_model, "ps ", 3) ||
216
0
     !_cups_strncasecmp(make_and_model, "colorpass", 9))
217
0
  {
218
   /*
219
    * Canon...
220
    */
221
222
0
    snprintf(buffer, bufsize, "Canon %s", make_and_model);
223
0
  }
224
0
  else if (!_cups_strncasecmp(make_and_model, "designjet", 9) ||
225
0
           !_cups_strncasecmp(make_and_model, "deskjet", 7))
226
0
  {
227
   /*
228
    * HP...
229
    */
230
231
0
    snprintf(buffer, bufsize, "HP %s", make_and_model);
232
0
  }
233
0
  else
234
0
    strlcpy(buffer, make_and_model, bufsize);
235
236
 /*
237
  * Clean up the make...
238
  */
239
240
0
  if (!_cups_strncasecmp(buffer, "agfa", 4))
241
0
  {
242
   /*
243
    * Replace with AGFA (all uppercase)...
244
    */
245
246
0
    buffer[0] = 'A';
247
0
    buffer[1] = 'G';
248
0
    buffer[2] = 'F';
249
0
    buffer[3] = 'A';
250
0
  }
251
0
  else if (!_cups_strncasecmp(buffer, "Hewlett-Packard hp ", 19))
252
0
  {
253
   /*
254
    * Just put "HP" on the front...
255
    */
256
257
0
    buffer[0] = 'H';
258
0
    buffer[1] = 'P';
259
0
    _cups_strcpy(buffer + 2, buffer + 18);
260
0
  }
261
0
  else if (!_cups_strncasecmp(buffer, "Hewlett-Packard ", 16))
262
0
  {
263
   /*
264
    * Just put "HP" on the front...
265
    */
266
267
0
    buffer[0] = 'H';
268
0
    buffer[1] = 'P';
269
0
    _cups_strcpy(buffer + 2, buffer + 15);
270
0
  }
271
0
  else if (!_cups_strncasecmp(buffer, "Lexmark International", 21))
272
0
  {
273
   /*
274
    * Strip "International"...
275
    */
276
277
0
    _cups_strcpy(buffer + 8, buffer + 21);
278
0
  }
279
0
  else if (!_cups_strncasecmp(buffer, "herk", 4))
280
0
  {
281
   /*
282
    * Replace with LHAG...
283
    */
284
285
0
    buffer[0] = 'L';
286
0
    buffer[1] = 'H';
287
0
    buffer[2] = 'A';
288
0
    buffer[3] = 'G';
289
0
  }
290
0
  else if (!_cups_strncasecmp(buffer, "linotype", 8))
291
0
  {
292
   /*
293
    * Replace with LHAG...
294
    */
295
296
0
    buffer[0] = 'L';
297
0
    buffer[1] = 'H';
298
0
    buffer[2] = 'A';
299
0
    buffer[3] = 'G';
300
0
    _cups_strcpy(buffer + 4, buffer + 8);
301
0
  }
302
303
 /*
304
  * Remove trailing whitespace and return...
305
  */
306
307
0
  for (bufptr = buffer + strlen(buffer) - 1;
308
0
       bufptr >= buffer && _cups_isspace(*bufptr);
309
0
       bufptr --);
310
311
0
  bufptr[1] = '\0';
312
313
0
  return (buffer[0] ? buffer : NULL);
314
0
}