// File: /workspace/github_c_makefile_star2_O2/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, 0xc(%rsp)
movq %rcx, 0x18(%rsp)
movq %rdx, %rbx
movq %rsi, %r13
movq %rdi, %rbp
movq %rsi, (%r9)
movq %rsi, %rdi
callq 0x23b0
movq %rax, %r12
movq %rax, %rdi
callq 0xba23
cmpl $0x0, 0x222d8(%rip)     # 0x2b38c
jle 0x90d6
leaq 0xbff8(%rip), %rdi      # 0x150b5
leaq 0xb21a(%rip), %rsi      # 0x142de
movl $0x62c, %edx            # imm = 0x62C
movq %rbx, %rcx
movq %r12, %r8
xorl %eax, %eax
callq 0xc2a1
movq %rbx, %rdi
callq 0x2110
movq %r12, %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x20a0
pushq $0x1
popq %r14
testq %r12, %r12
je 0x94bc
testl %eax, %eax
jne 0x94bc
cmpl $0x0, 0x22284(%rip)     # 0x2b38c
jle 0x912a
leaq 0xbfe3(%rip), %rdi      # 0x150f4
leaq 0xb1c6(%rip), %rsi      # 0x142de
movl $0x635, %edx            # imm = 0x635
movq %rbx, %rcx
movq %r12, %r8
xorl %eax, %eax
callq 0xc2a1
movq %rbx, %rdi
callq 0x2110
movzbl (%r13,%rax), %ecx
cmpq $0x3d, %rcx
ja 0x921c
movabsq $0x2000040100000200, %rdx # imm = 0x2000040100000200
btq %rcx, %rdx
jae 0x921c
movq %r13, %rdx
addq %rax, %r13
notq %rax
addq %r13, %rax
movq %rdx, 0x10(%rsp)
cmpq %rdx, %rax
jb 0x918d
movzbl (%rax), %eax
cmpq $0x3b, %rax
ja 0x921c
movabsq $0xc00000100000200, %rdx # imm = 0xC00000100000200
btq %rax, %rdx
jae 0x921c
cmpb $0x2a, %cl
jne 0x91da
cmpl $0x0, 0x221f3(%rip)     # 0x2b38c
jle 0x91b5
leaq 0xbf8b(%rip), %rdi      # 0x1512d
leaq 0xb135(%rip), %rsi      # 0x142de
movl $0x686, %edx            # imm = 0x686
xorl %eax, %eax
callq 0xc2a1
movslq 0xc(%rsp), %r8
movq %rbx, %rsi
movq 0x10(%rsp), %r13
movq %r13, %rdx
movq 0x18(%rsp), %rcx
movq %r15, %r9
callq 0x8dbc
xorl %r14d, %r14d
jmp 0x94bc
callq 0x23f0
movq %rax, %r14
movq (%rax), %rax
movsbq (%r13), %rcx
incq %r13
testb $0x20, 0x1(%rax,%rcx,2)
jne 0x91e5
testb %cl, %cl
je 0x9305
movq %r15, 0x20(%rsp)
pushq $0x3
popq %r15
cmpb $0x3d, (%r13)
jne 0x922d
movq %rbp, %rdi
movl %r15d, %esi
callq 0x7d08
incq %r13
jmp 0x9205
movq %r12, %rdi
callq 0x2030
pushq $0x1
popq %r14
jmp 0x94fb
leaq -0x1(%r13), %r15
movq %r15, %rdi
callq 0x2110
addq %r13, %rax
addq $-0x2, %rax
movq 0x20(%rsp), %rcx
movq %rax, (%rcx)
cmpq %r15, %rax
jbe 0x9263
movq (%r14), %rcx
movsbq (%rax), %rdx
testb $0x20, 0x1(%rcx,%rdx,2)
je 0x9263
movb $0x0, (%rax)
decq %rax
jmp 0x9248
cmpb $0x3d, (%r15)
je 0x9277
pushq $0x8
popq %rsi
movq %rbp, %rdi
callq 0x7d08
movq %r15, %r13
movq (%r14), %rcx
movsbq (%r13), %rax
incq %r13
testb $0x20, 0x1(%rcx,%rax,2)
jne 0x927a
leaq -0x1(%r13), %r14
cmpl $0x0, 0x220f8(%rip)     # 0x2b38c
movq 0x20(%rsp), %r15
jle 0x92bb
leaq 0xbf5b(%rip), %rdi      # 0x151fd
leaq 0xb035(%rip), %rsi      # 0x142de
movl $0x6b5, %edx            # imm = 0x6B5
movq %r14, %rcx
xorl %eax, %eax
callq 0xc2a1
movb (%r14), %al
movl 0x220cb(%rip), %ecx     # 0x2b38c
cmpb $0x22, %al
jne 0x9342
testl %ecx, %ecx
jle 0x92e3
leaq 0xbf74(%rip), %rdi      # 0x15244
leaq 0xb007(%rip), %rsi      # 0x142de
movl $0x6ca, %edx            # imm = 0x6CA
xorl %eax, %eax
callq 0xc2a1
pushq $0x1
popq %r14
movzbl (%r13), %eax
cmpl $0x22, %eax
jne 0x937c
movq %rbp, %rdi
movl %r14d, %esi
callq 0x7d08
incq %r13
jmp 0x92e7
cmpl $0x0, 0x22080(%rip)     # 0x2b38c
jle 0x950d
decq %r13
leaq 0xbe7c(%rip), %rdi      # 0x15198
leaq 0xafbb(%rip), %rsi      # 0x142de
xorl %r14d, %r14d
movl $0x695, %edx            # imm = 0x695
movq %rbx, %rcx
movq %r13, %r8
xorl %eax, %eax
callq 0xc2a1
movq 0x10(%rsp), %r13
jmp 0x94bc
testl %ecx, %ecx
jle 0x9360
leaq 0xbf7e(%rip), %rdi      # 0x152cb
leaq 0xaf8a(%rip), %rsi      # 0x142de
movl $0x6f4, %edx            # imm = 0x6F4
xorl %eax, %eax
callq 0xc2a1
leaq 0xbf5e(%rip), %rsi      # 0x152c5
movq %r14, %rdi
callq 0x2300
movq %r14, %r13
testq %rax, %rax
je 0x93c5
movq %rax, %r14
jmp 0x93bb
testl %eax, %eax
je 0x93c5
leaq 0x1(%r13), %rdi
pushq $0x22
popq %rsi
callq 0x2120
testq %rax, %rax
je 0x9519
movq %rax, %r14
cmpl $0x0, 0x21fed(%rip)     # 0x2b38c
jle 0x93bb
leaq 0xbee0(%rip), %rdi      # 0x15288
leaq 0xaf2f(%rip), %rsi      # 0x142de
movl $0x6d7, %edx            # imm = 0x6D7
xorl %eax, %eax
callq 0xc2a1
movb $0x0, (%r14)
incq %r14
movq %r14, (%r15)
cmpl $0x0, 0x21fc0(%rip)     # 0x2b38c
jle 0x93eb
leaq 0xbe28(%rip), %rdi      # 0x151fd
leaq 0xaf02(%rip), %rsi      # 0x142de
movl $0x702, %edx            # imm = 0x702
movq %r13, %rcx
xorl %eax, %eax
callq 0xc2a1
movzbl (%r13), %eax
cmpl $0x27, %eax
je 0x940c
cmpl $0x22, %eax
jne 0x9469
movq %r13, %rdi
callq 0x2110
cmpb $0x22, -0x1(%r13,%rax)
je 0x941c
jmp 0x9469
movq %r13, %rdi
callq 0x2110
cmpb $0x27, -0x1(%r13,%rax)
jne 0x9469
movq %r13, %rdi
callq 0x2110
movq %rax, %r14
cmpl $0x0, 0x21f5e(%rip)     # 0x2b38c
jle 0x944d
leaq 0xbedc(%rip), %rdi      # 0x15313
leaq 0xaea0(%rip), %rsi      # 0x142de
movl $0x709, %edx            # imm = 0x709
movq %r13, %rcx
xorl %eax, %eax
callq 0xc2a1
addl $-0x2, %r14d
movq %r13, %rax
testl %r14d, %r14d
jle 0x9466
movb 0x1(%rax), %cl
movb %cl, (%rax)
incq %rax
decl %r14d
jmp 0x9454
movb $0x0, (%rax)
movslq 0xc(%rsp), %rsi
leaq 0xdbeb(%rip), %rdx      # 0x17060
xorl %ebp, %ebp
movq 0x18(%rsp), %rdi
movq %r13, %rcx
xorl %eax, %eax
callq 0x2140
cmpl $0x0, 0x21eff(%rip)     # 0x2b38c
movl $0x0, %r14d
movq 0x10(%rsp), %r13
jle 0x94c7
leaq 0xbeb7(%rip), %rdi      # 0x15358
leaq 0xae36(%rip), %rsi      # 0x142de
xorl %r14d, %r14d
movl $0x716, %edx            # imm = 0x716
movq 0x18(%rsp), %rcx
xorl %eax, %eax
callq 0xc2a1
cmpl $0x0, 0x21ec9(%rip)     # 0x2b38c
setg %bpl
movq %r12, %rdi
callq 0x2030
testb %bpl, %bpl
je 0x94fb
movq (%r15), %r9
movq %r13, (%rsp)
leaq 0xbeb3(%rip), %rdi      # 0x15395
leaq 0xadf5(%rip), %rsi      # 0x142de
movl $0x721, %edx            # imm = 0x721
movl %r14d, %ecx
movq %rbx, %r8
xorl %eax, %eax
callq 0xc2a1
movl %r14d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %ebp, %ebp
xorl %r14d, %r14d
movq 0x10(%rsp), %r13
jmp 0x94c7
testq %rbp, %rbp
je 0x9529
pushq $0x2
popq %rsi
movq %rbp, %rdi
callq 0x7d08
leaq 0xbd95(%rip), %rsi      # 0x152c5
movq %r13, %rdi
callq 0x2300
jmp 0x9372