File: trigger_user_name.c

package info (click to toggle)
fis-gtm 7.1-006-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 32,908 kB
  • sloc: ansic: 344,906; asm: 5,184; csh: 4,859; sh: 2,000; awk: 294; makefile: 73; sed: 13
file content (131 lines) | stat: -rw-r--r-- 4,725 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/****************************************************************
 *								*
 *	Copyright 2010, 2014 Fidelity Information Services, Inc	*
 *								*
 *	This source code contains the intellectual property	*
 *	of its copyright holder(s), and is made available	*
 *	under a license.  If you do not know the terms of	*
 *	the license, please stop and do not read further.	*
 *								*
 ****************************************************************/

#include "mdef.h"

#include "gtm_ctype.h"
#include "gtm_string.h"
#include <rtnhdr.h>
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "gv_trigger.h"
#include "trigger.h"
#include "trigger_user_name.h"

#define NOLENGTH  -1

/* A quick heuristic to determine if the trigger name is user defined or auto
 * generated. Detect an interior (not at the end) # sign in the subject string
 * This is intended for use on valid trigger names, do not use this for
 * validation */
boolean_t trigger_user_name(char *trigger_value, int trigger_value_len)
{
	char		*ptr;

	ptr = memchr(trigger_value, TRIGNAME_SEQ_DELIM, trigger_value_len);
	return ((NULL == ptr) || ((trigger_value_len - 1) == (int)(ptr - trigger_value)));
}

/* Function returns the length of the trigger name or the character position of
 * the failure. There are two valid types of names here defined by the following
 * PATCODES
 * - Delete by user defined name:	  ?1(1"%",1A).27(1A,1N).1(1"#",1"*")
 * - Delete by auto generated name:	  ?1(1"%",1A).20(1A,1N)1"#"1(1.6N.1"#",1"*")
 * Keep in mind that this function does not have any side-effects and does not strip off
 * a trailing # sign or wild card
 */
int validate_input_trigger_name(char *trigger_name, uint4 trigger_name_len, boolean_t *wildcard_ptr)
{
	char		*ptr, *tail;
	uint4		len, name_len, num_len, max_len;
	boolean_t	wild, poundtail, firstdigit;

	if (0 == trigger_name_len)
		/* reject zero lengths, use -1 because returning 0 for 0 won't signal an error */
		return NOLENGTH;
	name_len = num_len = 0;
	ptr = trigger_name;
	len = trigger_name_len;
	tail = ptr + (len - 1);
	assert (ptr >= trigger_name);
	if (MAX_MIDENT_LEN < trigger_name_len)
		/* reject strings with super long lengths */
		return MAX_USER_TRIGNAME_LEN;
	if (!ISALPHA_ASCII(*ptr) && ('%' != *ptr))
		/* first char must be alpha or '%' sign */
		return INTCAST(ptr - trigger_name);
	name_len++;	/* to record first alpha byte that has already been processed */
	if ('*' == *tail)
	{	/* strip the wild card to skip checking it */
		wild = TRUE;
		tail--;
		len--;
	} else
		wild = FALSE;
	if (wildcard_ptr)
		*wildcard_ptr = wild;
	if (tail == ptr)
		/* special case to return sooner for a single character name */
		return INTCAST(ptr - trigger_name) + 1 + ((wild) ? 1 : 0);
	if (trigger_user_name(trigger_name, trigger_name_len))
	{	/* user defined name, use MAX_USER_TRIGNAME_LEN as max_len */
		max_len = MAX_USER_TRIGNAME_LEN;
		if (wild)
			name_len++;
	} else
		max_len = MAX_AUTO_TRIGNAME_LEN; /* auto generated name, use MAX_AUTO_TRIGNAME_LEN as max_len */
	poundtail = (TRIGNAME_SEQ_DELIM == *tail);
	if (MAX_USER_TRIGNAME_LEN + ((poundtail) ? 1 : 0) < trigger_name_len)
		/* name, must be under 28 chars (MAX_USER_TRIGNAME_LEN), but increment
		 * by one to forgive a trailing # sign, the 29th char */
		return max_len;
	while (++ptr <= tail && TRIGNAME_SEQ_DELIM != *ptr)
	{
		if ((!ISALNUM_ASCII(*ptr)) || (max_len < ++name_len))
			/* reject non-ALPHA-NUMERICS until first # sign or string end */
			return INTCAST(ptr - trigger_name);
		if (ptr == tail)
			break;
	}
	assert (ptr >= trigger_name);
	if (tail <= ptr)
		/* if the above loop terminated on this we're done, add in the wild card as necessary */
		return INTCAST(ptr - trigger_name) + 1 + ((wild) ? 1 : 0);
	if (wild)
		/* reject anything between the first # sign and wild card */
		return INTCAST(ptr - trigger_name);
	firstdigit = TRUE;
	while ((++ptr <= tail) && (TRIGNAME_SEQ_DELIM != *ptr))
	{ /* validate the numeric portion of the auto generated name */
		if (firstdigit)
		{
			/* reject number starting with 0 as that is not possible in auto generated name */
			if ('0' == *ptr)
				return INTCAST(ptr - trigger_name);
			firstdigit = FALSE;
		}
		if ((!ISDIGIT_ASCII(*ptr)) || (NUM_TRIGNAME_SEQ_CHARS < ++num_len))
			/* reject non-numeric or reject aaa#1234567 */
			return INTCAST(ptr - trigger_name);
		if (ptr == tail)
			break;
	}
	if (0 == num_len)
		/* reject aaa##  aka no numbers between adjacent '#' signs */
		return INTCAST(ptr - trigger_name);
	assert (ptr >= trigger_name);
	/* anything after the second # sign, then (ptr - trigger_name) + 1 != trigger_name_len */
	return INTCAST(ptr - trigger_name) + 1;
}