// File: /workspace/github_c_makefile_star2_O1/inflex[P]ripMIME/MIME_headers.c
// Function: MIMEH_parse_header_parameter
int MIMEH_parse_header_parameter( struct MIMEH_header_info *hinfo,  char *data, char *searchstr, char *output_value, int output_value_size, char **data_end_point  )
{
    int return_value = 0;
    char *p;
    char *hl;

    // Set the data end point to be the beginning of the data, as we
    //      have not yet searched through any of the header data
    *data_end_point = data;

    // Duplicate and convert to lowercase the header data
    //      that we have been provided with.
    hl = strdup(data);
    //PLD_strlower((unsigned char *)hl);
    PLD_strlower(hl);

    if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: Seeking '%s' in '%s'", FL, searchstr, hl);

    // Look for the search string we're after (ie, filename, name, location etc)
    if (strncmp(hl,searchstr,strlen(searchstr))==0) p = hl; else p = NULL;
    //  p = strstr (hl, searchstr); //TESTING
    if (p != NULL)
    {
        char *string = NULL;

        if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: found %s in %s", FL, searchstr, p);

        // Work out where in the -original- string the located parameter is.
        //      We need to work from the original string because we need to
        //      preserve case and our searching string is in _lower-case_.
        //
        //  After we've located it, we offset the pointer past the string we
        //      searched for.  At this position, we should see a separator of
        //      some type in the set [*;:=\t ].

        string = p -hl +data +strlen(searchstr);

        /**
         ** After searching for our parameter, if we've got a
         ** basic match via strstr, we should then proceed to
         ** check that the characters either side of it are
         ** relevant to a typical parameter specification
         **
         ** the characters *, =, <space> and tab can succeed a
         ** parameter name.
         **/
        switch (*string) {
            case '*':
            case '=':
            case ' ':
            case '\t':
                /**
                 ** Permitted characters were found after the parameter name
                 ** so continue on...
                 **/
                break;
            default:
                /**
                 ** Something other than the permitted characters was found,
                 ** this implies (assumed) that the string match was actually
                 ** just a bit of good luck, return to caller
                 **/
                if (hl) free(hl);
                return 1;
        } /** Switch **/

        /**
         ** Don't forget to also test the character _BEFORE_ the search string
         **/
        if (1)
        {
            char *before_string;

            before_string = string -1 -strlen(searchstr);
            if (before_string >= data)
            {
                /**
                 ** The characters, <space>, <tab>, ;, : may preceed a parameter name
                 **/
                switch (*(before_string)) {
                    case ';':
                    case ':':
                    case ' ':
                    case '\t':
                        /**
                         ** Permitted characters were found after the parameter name
                         ** so continue on...
                         **/
                        break;
                    default:
                        /**
                         ** Something other than the permitted characters was found,
                         ** this implies (assumed) that the string match was actually
                         ** just a bit of good luck, return to caller
                         **/
                        if (hl) free(hl);
                        return 1;
                } /** Switch before_string **/
            } /** if before_string > data **/
        } /** 1 **/


        // If the char is a '*', this means we've got a multivalue parameter
        //      which needs to be decoded (ie, name*1*=foo name*2*=bar )
        if (*string == '*')
        {
            DMIMEH LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: Found a '*' after the name, so attempting multipart value decode",FL);

            // PLD:DEV:11/08/2004-18H30
            //  Issue: RFC2231 handling
            return_value = MIMEH_recompose_multivalue( hinfo, searchstr, data, output_value, output_value_size, data_end_point);


        } else {

            // skip any spaces
            while (isspace((int) *string )) string++;

            //if ( *string != '=' )
            if ( *string == '\0' )
            {
                if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: In '%s' parsing, was expecting a '=' in the start of '%s'\n", FL, searchstr, string );

            }
            else {
                char *endchar;

                // Eliminate multiple = separators.
                // Reference: c030804-006a
                //  PLD:DEV: 11/08/2004-15H15
                while ((*(string +1) == '=')&&(*(string+1) != '\0')) { string++; MIMEH_set_defect(hinfo,MIMEH_DEFECT_MULTIPLE_EQUALS_SEPARATORS); }


                // Get the end of our string
                endchar = string +strlen(string) -1;
                *data_end_point = endchar;

                // Strip off trailing whitespace
                while ((endchar > string)&&(isspace((int)*endchar)))
                {
                    *endchar = '\0';
                    endchar--;
                }

                // we are at the '=' in the header, so skip it
                if (*string == '=') string++;
                else {
                    MIMEH_set_defect(hinfo,MIMEH_DEFECT_MISSING_SEPARATORS);
                }

                // skip any spaces... again
                while ( isspace((int) *string ) ) string++;

                DMIMEH LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: Extracting value out of '%s'",FL,string);

                // Because of all the potential exploits and bad behaviour
                //      we have to be really careful about how we determine
                //      what the enclosed string is for our parameter.
                //
                //  Previously we could _assume_ that we just get the last
                //      quote (") on the line and copy out what was between,
                //      unfortunately that doesn't work anymore. Instead now
                //      we have to step along the data stream one char at a
                //      time and make decisions along the way.

                switch (*string) {
                    case '\"':
                    {
                        // If our first char is a quote, then we'll then try and find
                        //      the second quote which closes the string, alas, this is
                        //      not always present in the header data, either due to a
                        //      broken MUA or due to an exploit attempt.
                        char *string_end;

                        DMIMEH LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: Using quoted-string tests",FL);

                        // Remove multiple-sequential quotes
                        string++;
                        while ((*string != '\0')&&(*string == '\"')){ string++; MIMEH_set_defect(hinfo,MIMEH_DEFECT_MULTIPLE_QUOTES); }

                        if (*string == '\0') break; // 20071030-0958: Added by Claudio Jeker - prevents overflow.

                        // Find the next quote which isn't sequential to the above
                        //      quotes that we just skipped over
                        string_end = strchr(string+1, '\"');
                        if (string_end != NULL)
                        {
                            DMIMEH LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: End of value found",FL);
                            *string_end = '\0';
                            *data_end_point = string_end +1;
                        } else {
                            // If string_end == NULL
                            //
                            // If we didn't find any more quotes, that
                            //      means we've probably got an unbalanced string (oh joy)
                            //      so then we convert to looking for other items such as
                            //      ;\n\r\t and space.
                            //
                            if (hinfo) MIMEH_set_defect(hinfo,MIMEH_DEFECT_UNBALANCED_QUOTES);
                            string_end = strpbrk(string,"; \n\r\t");
                            if (string_end != NULL)
                            {
                                *string_end = '\0';
                                *data_end_point = string_end +1;
                            } else {
                                // There is no termination to the string, instead the
                                //      end of the string is \0.
                            }
                        }
                    }
                    break;

                    default:
                    {
                        char *string_end;

                        DMIMEH LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: Using NON-quoted-string tests",FL);
                        string_end = strpbrk(string,"; \n\r\t");
                        if (string_end != NULL)
                        {
                            *string_end = '\0';
                            *data_end_point = string_end +1;
                        } else {
                            // There is no termination to the string, instead the
                            //      end of the string is \0.
                        }
                    }
                    break;
                } /** end of switch **/

                DMIMEH LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: Extracting value out of '%s'",FL,string);
                // Trim up and leading/trailing quotes
                if (((*string == '\"')&&(*(string +strlen(string)-1) == '\"'))
                        || ((*string == '\'')&&(*(string +strlen(string)-1) == '\'')) )
                {
                    int slen = strlen(string) -2;
                    char *s = string;
                    if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse-header_parameter:DEBUG: Stripping quotes from '%s'",FL,string);
                    while (slen > 0)
                    {
                        *s = *(s+1);
                        s++;
                        slen--;
                    }
                    *s = '\0';

                }

                // Now that our string is all cleaned up, save it to our output value
                snprintf( output_value, output_value_size, "%s", string );
                if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: Final value = '%s'",FL, output_value);
            } // If the first non-whitespace char wasn't a '='
        } // If the first char after the search-string wasn't a '*'

    }
    else {
        return_value = 1;
    }

    if (hl != NULL) free(hl);

    if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse_header_parameter:DEBUG: [return=%d] Done seeking for '%s' data_end_point=%p (from %p)",FL, return_value, searchstr, *data_end_point, data);

    return return_value;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r9, %r15
movl %r8d, 0x14(%rsp)
movq %rcx, 0x20(%rsp)
movq %rdx, %rbx
movq %rsi, %rbp
movq %rdi, %r13
movq %rsi, (%r9)
movq %rsi, %rdi
callq 0x23b0
movq %rax, %r12
movq %rax, %rdi
callq 0xbf91
cmpl $0x0, 0x22f83(%rip)     # 0x2c38c
jle 0x942b
leaq 0xcc73(%rip), %rdi      # 0x16085
leaq 0xbe95(%rip), %rsi      # 0x152ae
movl $0x62c, %edx            # imm = 0x62C
movq %rbx, %rcx
movq %r12, %r8
xorl %eax, %eax
callq 0xc960
movq %rbx, %rdi
callq 0x2110
movq %r12, %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x20a0
movl $0x1, %r14d
testq %r12, %r12
je 0x9852
testl %eax, %eax
jne 0x9852
cmpl $0x0, 0x22f2d(%rip)     # 0x2c38c
jle 0x9481
leaq 0xcc5c(%rip), %rdi      # 0x160c4
leaq 0xbe3f(%rip), %rsi      # 0x152ae
movl $0x635, %edx            # imm = 0x635
movq %rbx, %rcx
movq %r12, %r8
xorl %eax, %eax
callq 0xc960
movq %rbx, %rdi
callq 0x2110
movzbl (%rbp,%rax), %ecx
cmpq $0x3d, %rcx
ja 0x95b0
movabsq $0x2000040100000200, %rdx # imm = 0x2000040100000200
btq %rcx, %rdx
jae 0x95b0
movq %rbp, %rdx
addq %rax, %rbp
notq %rax
addq %rbp, %rax
movq %rdx, 0x18(%rsp)
cmpq %rdx, %rax
jb 0x94e3
movzbl (%rax), %eax
cmpq $0x3b, %rax
ja 0x95b0
movabsq $0xc00000100000200, %rdx # imm = 0xC00000100000200
btq %rax, %rdx
jae 0x95b0
cmpb $0x2a, %cl
jne 0x9530
cmpl $0x0, 0x22e9d(%rip)     # 0x2c38c
jle 0x950b
leaq 0xcc05(%rip), %rdi      # 0x160fd
leaq 0xbdaf(%rip), %rsi      # 0x152ae
movl $0x686, %edx            # imm = 0x686
xorl %eax, %eax
callq 0xc960
movslq 0x14(%rsp), %r8
movq %rbx, %rsi
movq 0x18(%rsp), %rbp
movq %rbp, %rdx
movq 0x20(%rsp), %rcx
movq %r15, %r9
callq 0x9111
xorl %r14d, %r14d
jmp 0x9852
movq %r15, 0x8(%rsp)
callq 0x23f0
movq %rax, %r14
movq (%rax), %rax
movsbq (%rbp), %rcx
incq %rbp
testb $0x20, 0x1(%rax,%rcx,2)
jne 0x9540
leaq -0x1(%rbp), %r15
testb %cl, %cl
je 0x96b2
cmpb $0x3d, (%rbp)
jne 0x957f
movq %rbp, %r15
movq %r13, %rdi
movl $0x3, %esi
callq 0x802f
incq %rbp
cmpb $0x3d, 0x1(%r15)
je 0x9561
leaq -0x1(%rbp), %r15
movq %r15, %rdi
callq 0x2110
addq %r15, %rax
decq %rax
movq 0x8(%rsp), %rcx
movq %rax, (%rcx)
cmpq %r15, %rax
jbe 0x95cc
movq (%r14), %rcx
movsbq (%rax), %rdx
testb $0x20, 0x1(%rcx,%rdx,2)
je 0x95cc
movb $0x0, (%rax)
decq %rax
jmp 0x9595
movl $0x1, %r14d
testq %r12, %r12
je 0x988f
movq %r12, %rdi
callq 0x2030
jmp 0x988f
cmpb $0x3d, (%r15)
je 0x95e2
movq %r13, %rdi
movl $0x8, %esi
callq 0x802f
movq %r15, %rbp
movq (%r14), %rax
movsbq (%rbp), %rcx
incq %rbp
testb $0x20, 0x1(%rax,%rcx,2)
jne 0x95e5
leaq -0x1(%rbp), %r14
cmpl $0x0, 0x22d8d(%rip)     # 0x2c38c
jle 0x961e
leaq 0xcbc5(%rip), %rdi      # 0x161cd
leaq 0xbc9f(%rip), %rsi      # 0x152ae
movl $0x6b5, %edx            # imm = 0x6B5
movq %r14, %rcx
xorl %eax, %eax
callq 0xc960
cmpb $0x22, (%r14)
movl 0x22d64(%rip), %eax     # 0x2c38c
jne 0x96e0
testl %eax, %eax
jle 0x965e
leaq 0xcbdb(%rip), %rdi      # 0x16214
leaq 0xbc6e(%rip), %rsi      # 0x152ae
movl $0x6ca, %edx            # imm = 0x6CA
xorl %eax, %eax
callq 0xc960
jmp 0x965e
movq %r13, %rdi
movl $0x1, %esi
callq 0x802f
incq %rbp
movzbl (%rbp), %eax
cmpl $0x22, %eax
je 0x964e
testl %eax, %eax
je 0x9741
leaq 0x1(%rbp), %rdi
movl $0x22, %esi
callq 0x2120
testq %rax, %rax
je 0x98a1
movq %rax, %r15
cmpl $0x0, 0x22cfc(%rip)     # 0x2c38c
jle 0x9718
leaq 0xcbbb(%rip), %rdi      # 0x16258
leaq 0xbc0a(%rip), %rsi      # 0x152ae
movl $0x6d7, %edx            # imm = 0x6D7
xorl %eax, %eax
callq 0xc960
jmp 0x9718
cmpl $0x0, 0x22cd3(%rip)     # 0x2c38c
jle 0x972c
leaq 0xcaa6(%rip), %rdi      # 0x16168
leaq 0xbbe5(%rip), %rsi      # 0x152ae
xorl %r14d, %r14d
movl $0x695, %edx            # imm = 0x695
movq %rbx, %rcx
movq %r15, %r8
xorl %eax, %eax
callq 0xc960
jmp 0x972f
testl %eax, %eax
jle 0x96fe
leaq 0xcbb0(%rip), %rdi      # 0x1629b
leaq 0xbbbc(%rip), %rsi      # 0x152ae
movl $0x6f4, %edx            # imm = 0x6F4
xorl %eax, %eax
callq 0xc960
leaq 0xcb90(%rip), %rsi      # 0x16295
movq %r14, %rdi
callq 0x2300
testq %rax, %rax
je 0x973e
movq %rax, %r15
movq %r14, %rbp
movb $0x0, (%r15)
incq %r15
movq 0x8(%rsp), %rax
movq %r15, (%rax)
movq %rax, %r15
jmp 0x9746
xorl %r14d, %r14d
movq 0x8(%rsp), %r15
movq 0x18(%rsp), %rbp
jmp 0x9852
movq %r14, %rbp
movq 0x8(%rsp), %r15
cmpl $0x0, 0x22c3f(%rip)     # 0x2c38c
jle 0x976c
leaq 0xca77(%rip), %rdi      # 0x161cd
leaq 0xbb51(%rip), %rsi      # 0x152ae
movl $0x702, %edx            # imm = 0x702
movq %rbp, %rcx
xorl %eax, %eax
callq 0xc960
movzbl (%rbp), %r14d
cmpl $0x27, %r14d
je 0x9796
cmpl $0x22, %r14d
jne 0x9804
movq %rbp, %rdi
callq 0x2110
cmpb $0x22, -0x1(%rbp,%rax)
je 0x97a5
cmpb $0x27, %r14b
jne 0x9804
movq %rbp, %rdi
callq 0x2110
cmpb $0x27, -0x1(%rbp,%rax)
jne 0x9804
movq %rbp, %rdi
callq 0x2110
movq %rax, %r14
leal -0x2(%rax), %r15d
cmpl $0x0, 0x22bd1(%rip)     # 0x2c38c
jle 0x97da
leaq 0xcb1f(%rip), %rdi      # 0x162e3
leaq 0xbae3(%rip), %rsi      # 0x152ae
movl $0x709, %edx            # imm = 0x709
movq %rbp, %rcx
xorl %eax, %eax
callq 0xc960
movq %rbp, %rax
testl %r15d, %r15d
jle 0x97fc
leaq 0x1(%rbp), %rsi
movl %r15d, %edx
movq %rbp, %rdi
callq 0x2330
addl $-0x3, %r14d
leaq (%r14,%rbp), %rax
incq %rax
movb $0x0, (%rax)
movq 0x8(%rsp), %r15
movslq 0x14(%rsp), %rsi
leaq 0xe87d(%rip), %rdx      # 0x1808d
xorl %r14d, %r14d
movq 0x20(%rsp), %rdi
movq %rbp, %rcx
xorl %eax, %eax
callq 0x2140
cmpl $0x0, 0x22b63(%rip)     # 0x2c38c
movq 0x18(%rsp), %rbp
jle 0x9852
leaq 0xcaf1(%rip), %rdi      # 0x16328
leaq 0xba70(%rip), %rsi      # 0x152ae
xorl %r14d, %r14d
movl $0x716, %edx            # imm = 0x716
movq 0x20(%rsp), %rcx
xorl %eax, %eax
callq 0xc960
testq %r12, %r12
je 0x985f
movq %r12, %rdi
callq 0x2030
cmpl $0x0, 0x22b26(%rip)     # 0x2c38c
jle 0x988f
movq (%r15), %r9
movq %rbp, (%rsp)
leaq 0xcaef(%rip), %rdi      # 0x16365
leaq 0xba31(%rip), %rsi      # 0x152ae
movl $0x721, %edx            # imm = 0x721
movl %r14d, %ecx
movq %rbx, %r8
xorl %eax, %eax
callq 0xc960
movl %r14d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testq %r13, %r13
je 0x98b3
movq %r13, %rdi
movl $0x2, %esi
callq 0x802f
leaq 0xc9db(%rip), %rsi      # 0x16295
movq %rbp, %rdi
callq 0x2300
testq %rax, %rax
je 0x9741
movq %rax, %r15
jmp 0x9718