Bug Summary

File:util/fontxlfd.c
Location:line 445, column 2
Description:Value stored to 'ptr2' is never read

Annotated Source Code

1/*
2
3Copyright 1990, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29/*
30 * Author: Keith Packard, MIT X Consortium
31 */
32
33#ifdef HAVE_CONFIG_H1
34#include <config.h>
35#endif
36#include <X11/fonts/fontmisc.h>
37#include <X11/fonts/fontstruct.h>
38#include <X11/fonts/fontxlfd.h>
39#include <X11/fonts/fontutil.h>
40#include <X11/Xos.h>
41#include <math.h>
42#include <stdlib.h>
43#if defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV)
44#define NO_LOCALE
45#endif
46#ifndef NO_LOCALE
47#include <locale.h>
48#endif
49#include <ctype.h>
50#include <stdio.h> /* for sprintf() */
51
52static char *
53GetInt(char *ptr, int *val)
54{
55 if (*ptr == '*') {
56 *val = -1;
57 ptr++;
58 } else
59 for (*val = 0; *ptr >= '0' && *ptr <= '9';)
60 *val = *val * 10 + *ptr++ - '0';
61 if (*ptr == '-')
62 return ptr;
63 return (char *) 0;
64}
65
66#define minchar(p)((p).min_char_low + ((p).min_char_high << 8)) ((p).min_char_low + ((p).min_char_high << 8))
67#define maxchar(p)((p).max_char_low + ((p).max_char_high << 8)) ((p).max_char_low + ((p).max_char_high << 8))
68
69
70#ifndef NO_LOCALE
71static struct lconv *locale = 0;
72#endif
73static const char *radix = ".", *plus = "+", *minus = "-";
74
75static char *
76readreal(char *ptr, double *result)
77{
78 char buffer[80], *p1, *p2;
79
80#ifndef NO_LOCALE
81 /* Figure out what symbols apply in this locale */
82
83 if (!locale)
84 {
85 locale = localeconv();
86 if (locale->decimal_point && *locale->decimal_point)
87 radix = locale->decimal_point;
88 if (locale->positive_sign && *locale->positive_sign)
89 plus = locale->positive_sign;
90 if (locale->negative_sign && *locale->negative_sign)
91 minus = locale->negative_sign;
92 }
93#endif
94 /* Copy the first 80 chars of ptr into our local buffer, changing
95 symbols as needed. */
96 for (p1 = ptr, p2 = buffer;
97 *p1 && (p2 - buffer) < sizeof(buffer) - 1;
98 p1++, p2++)
99 {
100 switch(*p1)
101 {
102 case '~': *p2 = *minus; break;
103 case '+': *p2 = *plus; break;
104 case '.': *p2 = *radix; break;
105 default: *p2 = *p1;
106 }
107 }
108 *p2 = 0;
109
110 /* Now we have something that strtod() can interpret... do it. */
111 *result = strtod(buffer, &p1);
112 /* Return NULL if failure, pointer past number if success */
113 return (p1 == buffer) ? (char *)0 : (ptr + (p1 - buffer));
114}
115
116static char *
117xlfd_double_to_text(double value, char *buffer, int space_required)
118{
119 register char *p1;
120 int ndigits, exponent;
121
122#ifndef NO_LOCALE
123 if (!locale)
124 {
125 locale = localeconv();
126 if (locale->decimal_point && *locale->decimal_point)
127 radix = locale->decimal_point;
128 if (locale->positive_sign && *locale->positive_sign)
129 plus = locale->positive_sign;
130 if (locale->negative_sign && *locale->negative_sign)
131 minus = locale->negative_sign;
132 }
133#endif
134
135 if (space_required)
136 *buffer++ = ' ';
137
138 /* Render the number using printf's idea of formatting */
139 sprintf(buffer, "%.*le", XLFD_NDIGITS3, value);
140
141 /* Find and read the exponent value */
142 for (p1 = buffer + strlen(buffer);
143 *p1-- != 'e' && p1[1] != 'E';);
144 exponent = atoi(p1 + 2);
145 if (value == 0.0) exponent = 0;
146
147 /* Figure out how many digits are significant */
148 while (p1 >= buffer && (!isdigit(*p1)((*__ctype_b_loc ())[(int) ((*p1))] & (unsigned short int
) _ISdigit)
|| *p1 == '0')) p1--;
149 ndigits = 0;
150 while (p1 >= buffer) if (isdigit(*p1--)((*__ctype_b_loc ())[(int) ((*p1--))] & (unsigned short int
) _ISdigit)
) ndigits++;
151
152 /* Figure out notation to use */
153 if (exponent >= XLFD_NDIGITS3 || ndigits - exponent > XLFD_NDIGITS3 + 1)
154 {
155 /* Scientific */
156 sprintf(buffer, "%.*le", ndigits - 1, value);
157 }
158 else
159 {
160 /* Fixed */
161 ndigits -= exponent + 1;
162 if (ndigits < 0) ndigits = 0;
163 sprintf(buffer, "%.*lf", ndigits, value);
164 if (exponent < 0)
165 {
166 p1 = buffer;
167 while (*p1 && *p1 != '0') p1++;
168 while (*p1++) p1[-1] = *p1;
169 }
170 }
171
172 /* Last step, convert the locale-specific sign and radix characters
173 to our own. */
174 for (p1 = buffer; *p1; p1++)
175 {
176 if (*p1 == *minus) *p1 = '~';
177 else if (*p1 == *plus) *p1 = '+';
178 else if (*p1 == *radix) *p1 = '.';
179 }
180
181 return buffer - space_required;
182}
183
184double
185xlfd_round_double(double x)
186{
187 /* Utility for XLFD users to round numbers to XLFD_NDIGITS
188 significant digits. How do you round to n significant digits on
189 a binary machine? */
190
191#if defined(i386) || defined(__i386__) || \
192 defined(ia64) || defined(__ia64__) || \
193 defined(__alpha__) || defined(__alpha) || \
194 defined(__hppa__) || \
195 defined(__amd64__) || defined(__amd64) || \
196 defined(sgi)
197#include <float.h>
198
199/* if we have IEEE 754 fp, we can round to binary digits... */
200
201#if (FLT_RADIX == 2) && (DBL_DIG == 15) && (DBL_MANT_DIG == 53)
202
203#ifndef M_LN20.69314718055994530942
204#define M_LN20.69314718055994530942 0.69314718055994530942
205#endif
206#ifndef M_LN102.30258509299404568402
207#define M_LN102.30258509299404568402 2.30258509299404568402
208#endif
209
210/* convert # of decimal digits to # of binary digits */
211#define XLFD_NDIGITS_2 ((int)(XLFD_NDIGITS3 * M_LN102.30258509299404568402 / M_LN20.69314718055994530942 + 0.5))
212
213 union conv_d {
214 double d;
215 unsigned char b[8];
216 } d;
217 int i,j,k,d_exp;
218
219 if (x == 0)
220 return x;
221
222 /* do minor sanity check for IEEE 754 fp and correct byte order */
223 d.d = 1.0;
224 if (sizeof(double) == 8 && d.b[7] == 0x3f && d.b[6] == 0xf0) {
225
226 /*
227 * this code will round IEEE 754 double to XLFD_NDIGITS_2 binary digits
228 */
229
230 d.d = x;
231 d_exp = (d.b[7] << 4) | (d.b[6] >> 4);
232
233 i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3;
234 j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07);
235 for (; i<7; i++) {
236 k = d.b[i] + j;
237 d.b[i] = k;
238 if (k & 0x100) j = 1;
239 else break;
240 }
241 if ((i==7) && ((d.b[6] & 0xf0) != ((d_exp<<4) & 0xf0))) {
242 /* mantissa overflow: increment exponent */
243 d_exp = (d_exp & 0x800 ) | ((d_exp & 0x7ff) + 1);
244 d.b[7] = d_exp >> 4;
245 d.b[6] = (d.b[6] & 0x0f) | (d_exp << 4);
246 }
247
248 i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3;
249 j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07);
250 d.b[i] &= ~(j-1);
251 for (;--i>=0;) d.b[i] = 0;
252
253 return d.d;
254 }
255 else
256#endif
257#endif /* i386 || __i386__ */
258 {
259 /*
260 * If not IEEE 754: Let printf() do it for you.
261 */
262
263 char buffer[40];
264
265 sprintf(buffer, "%.*lg", XLFD_NDIGITS3, x);
266 return atof(buffer);
267 }
268}
269
270static char *
271GetMatrix(char *ptr, FontScalablePtr vals, int which)
272{
273 double *matrix;
274
275 if (which == PIXELSIZE_MASK0x3)
276 matrix = vals->pixel_matrix;
277 else if (which == POINTSIZE_MASK0xc)
278 matrix = vals->point_matrix;
279 else return (char *)0;
280
281 while (isspace(*ptr)((*__ctype_b_loc ())[(int) ((*ptr))] & (unsigned short int
) _ISspace)
) ptr++;
282 if (*ptr == '[')
283 {
284 /* This is a matrix containing real numbers. It would be nice
285 to use strtod() or sscanf() to read the numbers, but those
286 don't handle '~' for minus and we cannot force them to use a
287 "." for the radix. We'll have to do the hard work ourselves
288 (in readreal()). */
289
290 if ((ptr = readreal(++ptr, matrix + 0)) &&
291 (ptr = readreal(ptr, matrix + 1)) &&
292 (ptr = readreal(ptr, matrix + 2)) &&
293 (ptr = readreal(ptr, matrix + 3)))
294 {
295 while (isspace(*ptr)((*__ctype_b_loc ())[(int) ((*ptr))] & (unsigned short int
) _ISspace)
) ptr++;
296 if (*ptr != ']')
297 ptr = (char *)0;
298 else
299 {
300 ptr++;
301 while (isspace(*ptr)((*__ctype_b_loc ())[(int) ((*ptr))] & (unsigned short int
) _ISspace)
) ptr++;
302 if (*ptr == '-')
303 {
304 if (which == POINTSIZE_MASK0xc)
305 vals->values_supplied |= POINTSIZE_ARRAY0x8;
306 else
307 vals->values_supplied |= PIXELSIZE_ARRAY0x2;
308 }
309 else ptr = (char *)0;
310 }
311 }
312 }
313 else
314 {
315 int value;
316 if ((ptr = GetInt(ptr, &value)))
317 {
318 vals->values_supplied &= ~which;
319 if (value > 0)
320 {
321 matrix[3] = (double)value;
322 if (which == POINTSIZE_MASK0xc)
323 {
324 matrix[3] /= 10.0;
325 vals->values_supplied |= POINTSIZE_SCALAR0x4;
326 }
327 else
328 vals->values_supplied |= PIXELSIZE_SCALAR0x1;
329 /* If we're concocting the pixelsize array from a scalar,
330 we will need to normalize element 0 for the pixel shape.
331 This is done in FontFileCompleteXLFD(). */
332 matrix[0] = matrix[3];
333 matrix[1] = matrix[2] = 0.0;
334 }
335 else if (value < 0)
336 {
337 if (which == POINTSIZE_MASK0xc)
338 vals->values_supplied |= POINTSIZE_WILDCARD0x20;
339 else
340 vals->values_supplied |= PIXELSIZE_WILDCARD0x10;
341 }
342 }
343 }
344 return ptr;
345}
346
347
348static void
349append_ranges(char *fname, int nranges, fsRange *ranges)
350{
351 if (nranges)
352 {
353 int i;
354
355 strcat(fname, "[");
356 for (i = 0; i < nranges && strlen(fname) < 1010; i++)
357 {
358 if (i) strcat(fname, " ");
359 sprintf(fname + strlen(fname), "%d",
360 minchar(ranges[i])((ranges[i]).min_char_low + ((ranges[i]).min_char_high <<
8))
);
361 if (ranges[i].min_char_low ==
362 ranges[i].max_char_low &&
363 ranges[i].min_char_high ==
364 ranges[i].max_char_high) continue;
365 sprintf(fname + strlen(fname), "_%d",
366 maxchar(ranges[i])((ranges[i]).max_char_low + ((ranges[i]).max_char_high <<
8))
);
367 }
368 strcat(fname, "]");
369 }
370}
371
372Bool
373FontParseXLFDName(char *fname, FontScalablePtr vals, int subst)
374{
375 register char *ptr;
376 register char *ptr1,
377 *ptr2,
378 *ptr3,
379 *ptr4;
380 register char *ptr5;
381 FontScalableRec tmpvals;
382 char replaceChar = '0';
383 char tmpBuf[1024];
384 int spacingLen;
385 int l;
386 char *p;
387
388 bzero(&tmpvals, sizeof(tmpvals))memset(&tmpvals,0,sizeof(tmpvals));
389 if (subst != FONT_XLFD_REPLACE_VALUE3)
390 *vals = tmpvals;
391
392 if (!(*(ptr = fname) == '-' || (*ptr++ == '*' && *ptr == '-')) || /* fndry */
393 !(ptr = strchr(ptr + 1, '-')) || /* family_name */
394 !(ptr1 = ptr = strchr(ptr + 1, '-')) || /* weight_name */
395 !(ptr = strchr(ptr + 1, '-')) || /* slant */
396 !(ptr = strchr(ptr + 1, '-')) || /* setwidth_name */
397 !(ptr = strchr(ptr + 1, '-')) || /* add_style_name */
398 !(ptr = strchr(ptr + 1, '-')) || /* pixel_size */
399 !(ptr = GetMatrix(ptr + 1, &tmpvals, PIXELSIZE_MASK0x3)) ||
400 !(ptr2 = ptr = GetMatrix(ptr + 1, &tmpvals, POINTSIZE_MASK0xc)) ||
401 !(ptr = GetInt(ptr + 1, &tmpvals.x)) || /* resolution_x */
402 !(ptr3 = ptr = GetInt(ptr + 1, &tmpvals.y)) || /* resolution_y */
403 !(ptr4 = ptr = strchr(ptr + 1, '-')) || /* spacing */
404 !(ptr5 = ptr = GetInt(ptr + 1, &tmpvals.width)) || /* average_width */
405 !(ptr = strchr(ptr + 1, '-')) || /* charset_registry */
406 strchr(ptr + 1, '-'))/* charset_encoding */
407 return FALSE0;
408
409 /* Lop off HP charset subsetting enhancement. Interpreting this
410 field requires allocating some space in which to return the
411 results. So, to prevent memory leaks, this procedure will simply
412 lop off and ignore charset subsetting, and initialize the
413 relevant vals fields to zero. It's up to the caller to make its
414 own call to FontParseRanges() if it's interested in the charset
415 subsetting. */
416
417 if (subst != FONT_XLFD_REPLACE_NONE0 &&
418 (p = strchr(strrchr(fname, '-'), '[')))
419 {
420 tmpvals.values_supplied |= CHARSUBSET_SPECIFIED0x40;
421 *p = '\0';
422 }
423
424 /* Fill in deprecated fields for the benefit of rasterizers that care
425 about them. */
426 tmpvals.pixel = (tmpvals.pixel_matrix[3] >= 0) ?
427 (int)(tmpvals.pixel_matrix[3] + .5) :
428 (int)(tmpvals.pixel_matrix[3] - .5);
429 tmpvals.point = (tmpvals.point_matrix[3] >= 0) ?
430 (int)(tmpvals.point_matrix[3] * 10 + .5) :
431 (int)(tmpvals.point_matrix[3] * 10 - .5);
432
433 spacingLen = ptr4 - ptr3 + 1;
434
435 switch (subst) {
436 case FONT_XLFD_REPLACE_NONE0:
437 *vals = tmpvals;
438 break;
439 case FONT_XLFD_REPLACE_STAR1:
440 replaceChar = '*';
441 case FONT_XLFD_REPLACE_ZERO2:
442 strcpy(tmpBuf, ptr2);
443 ptr5 = tmpBuf + (ptr5 - ptr2);
444 ptr3 = tmpBuf + (ptr3 - ptr2);
445 ptr2 = tmpBuf;
Value stored to 'ptr2' is never read
446 ptr = ptr1 + 1;
447
448 ptr = strchr(ptr, '-') + 1; /* skip weight */
449 ptr = strchr(ptr, '-') + 1; /* skip slant */
450 ptr = strchr(ptr, '-') + 1; /* skip setwidth_name */
451 ptr = strchr(ptr, '-') + 1; /* skip add_style_name */
452
453 if ((ptr - fname) + spacingLen + strlen(ptr5) + 10 >= (unsigned)1024)
454 return FALSE0;
455 *ptr++ = replaceChar;
456 *ptr++ = '-';
457 *ptr++ = replaceChar;
458 *ptr++ = '-';
459 *ptr++ = '*';
460 *ptr++ = '-';
461 *ptr++ = '*';
462 if (spacingLen > 2)
463 {
464 memmove(ptr, ptr3, spacingLen);
465 ptr += spacingLen;
466 }
467 else
468 {
469 *ptr++ = '-';
470 *ptr++ = '*';
471 *ptr++ = '-';
472 }
473 *ptr++ = replaceChar;
474 strcpy(ptr, ptr5);
475 *vals = tmpvals;
476 break;
477 case FONT_XLFD_REPLACE_VALUE3:
478 if (vals->values_supplied & PIXELSIZE_MASK0x3)
479 {
480 tmpvals.values_supplied =
481 (tmpvals.values_supplied & ~PIXELSIZE_MASK0x3) |
482 (vals->values_supplied & PIXELSIZE_MASK0x3);
483 tmpvals.pixel_matrix[0] = vals->pixel_matrix[0];
484 tmpvals.pixel_matrix[1] = vals->pixel_matrix[1];
485 tmpvals.pixel_matrix[2] = vals->pixel_matrix[2];
486 tmpvals.pixel_matrix[3] = vals->pixel_matrix[3];
487 }
488 if (vals->values_supplied & POINTSIZE_MASK0xc)
489 {
490 tmpvals.values_supplied =
491 (tmpvals.values_supplied & ~POINTSIZE_MASK0xc) |
492 (vals->values_supplied & POINTSIZE_MASK0xc);
493 tmpvals.point_matrix[0] = vals->point_matrix[0];
494 tmpvals.point_matrix[1] = vals->point_matrix[1];
495 tmpvals.point_matrix[2] = vals->point_matrix[2];
496 tmpvals.point_matrix[3] = vals->point_matrix[3];
497 }
498 if (vals->x >= 0)
499 tmpvals.x = vals->x;
500 if (vals->y >= 0)
501 tmpvals.y = vals->y;
502 if (vals->width >= 0)
503 tmpvals.width = vals->width;
504 else if (vals->width < -1) /* overload: -1 means wildcard */
505 tmpvals.width = -vals->width;
506
507
508 p = ptr1 + 1; /* weight field */
509 l = strchr(p, '-') - p;
510 sprintf(tmpBuf, "%*.*s", l, l, p);
511
512 p += l + 1; /* slant field */
513 l = strchr(p, '-') - p;
514 sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
515
516 p += l + 1; /* setwidth_name */
517 l = strchr(p, '-') - p;
518 sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
519
520 p += l + 1; /* add_style_name field */
521 l = strchr(p, '-') - p;
522 sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p);
523
524 strcat(tmpBuf, "-");
525 if ((tmpvals.values_supplied & PIXELSIZE_MASK0x3) == PIXELSIZE_ARRAY0x2)
526 {
527 char buffer[80];
528 strcat(tmpBuf, "[");
529 strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[0],
530 buffer, 0));
531 strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[1],
532 buffer, 1));
533 strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[2],
534 buffer, 1));
535 strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[3],
536 buffer, 1));
537 strcat(tmpBuf, "]");
538 }
539 else
540 {
541 sprintf(tmpBuf + strlen(tmpBuf), "%d",
542 (int)(tmpvals.pixel_matrix[3] + .5));
543 }
544 strcat(tmpBuf, "-");
545 if ((tmpvals.values_supplied & POINTSIZE_MASK0xc) == POINTSIZE_ARRAY0x8)
546 {
547 char buffer[80];
548 strcat(tmpBuf, "[");
549 strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[0],
550 buffer, 0));
551 strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[1],
552 buffer, 1));
553 strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[2],
554 buffer, 1));
555 strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[3],
556 buffer, 1));
557 strcat(tmpBuf, "]");
558 }
559 else
560 {
561 sprintf(tmpBuf + strlen(tmpBuf), "%d",
562 (int)(tmpvals.point_matrix[3] * 10.0 + .5));
563 }
564 sprintf(tmpBuf + strlen(tmpBuf), "-%d-%d%*.*s%d%s",
565 tmpvals.x, tmpvals.y,
566 spacingLen, spacingLen, ptr3, tmpvals.width, ptr5);
567 strcpy(ptr1 + 1, tmpBuf);
568 if ((vals->values_supplied & CHARSUBSET_SPECIFIED0x40) && !vals->nranges)
569 strcat(fname, "[]");
570 else
571 append_ranges(fname, vals->nranges, vals->ranges);
572 break;
573 }
574 return TRUE1;
575}
576
577fsRange *FontParseRanges(char *name, int *nranges)
578{
579 int n;
580 unsigned long l;
581 char *p1, *p2;
582 fsRange *result = (fsRange *)0;
583
584 name = strchr(name, '-');
585 for (n = 1; name && n < 14; n++)
586 name = strchr(name + 1, '-');
587
588 *nranges = 0;
589 if (!name || !(p1 = strchr(name, '['))) return (fsRange *)0;
590 p1++;
591
592 while (*p1 && *p1 != ']')
593 {
594 fsRange thisrange;
595
596 l = strtol(p1, &p2, 0);
597 if (p2 == p1 || l > 0xffff) break;
598 thisrange.max_char_low = thisrange.min_char_low = l & 0xff;
599 thisrange.max_char_high = thisrange.min_char_high = l >> 8;
600
601 p1 = p2;
602 if (*p1 == ']' || *p1 == ' ')
603 {
604 while (*p1 == ' ') p1++;
605 if (add_range(&thisrange, nranges, &result, TRUE1) != Successful85)
606 break;
607 }
608 else if (*p1 == '_')
609 {
610 l = strtol(++p1, &p2, 0);
611 if (p2 == p1 || l > 0xffff) break;
612 thisrange.max_char_low = l & 0xff;
613 thisrange.max_char_high = l >> 8;
614 p1 = p2;
615 if (*p1 == ']' || *p1 == ' ')
616 {
617 while (*p1 == ' ') p1++;
618 if (add_range(&thisrange, nranges, &result, TRUE1) != Successful85)
619 break;
620 }
621 }
622 else break;
623 }
624
625 return result;
626}