>

char 를 정의했습니다  다음과 같이 미리 정의 된 HTTP 포스트 문자열이있는 배열 :

char header[] = "POST /api/add HTTP/1.1\r\nHost: xxxxxxx:3000\r\nContent-Type: application/octet-stream; charset=utf-8\r\nContent-Length: 500\r\nName: ";
strcat(header, strDevicename); \\
strcat(header, "\r\n\r\n");

strDevicename   char 입니다  변수 이름은 모든 요청마다 변경되었습니다. 문제는 처음으로 실행할 때 작동하지만 Name 를 덮어 쓴 후에 작동합니다.   a96ed5ÿÿa96ed58e8355 와 함께 .

HTTP 포스트 헤더에서 C 언어를 사용하여 하나의 실시간 변경 변수로 두 개의 문자열을 추가하는 가장 좋은 방법은 무엇입니까?

  • 답변 # 1

    문제는 당신이 배열에 연결되어 있다는 것입니다 ( header ) 추가 공간이 없습니다 (C 배열의 크기를 변경할 수 없음).

    snprintf  여기에 더 잘 맞을 수 있습니다.

    strDevicename 의 최대 길이를 알고 있다면 고정 크기 버퍼를 사용할 수 있습니다 :

    const char header[] = "POST /api/add HTTP/1.1\r\nHost: xxxxxxx:3000\r\nContent-Type: application/octet-stream; charset=utf-8\r\nContent-Length: 500\r\nName: ";
    const char tail[] = "\r\n\r\n";
    char buf[(sizeof header - 1) + MAX_DEV_LENGTH + (sizeof tail - 1) + 1];
    /* sizeof would count the null byte in header & tail arrays. */
    snprintf(buf, sizeof buf, "%s%s%s", header, strDevicename, tail);
    
    

    strDevicename 인 경우  길이가 알려지지 않은 경우 asprintf 를 사용할 수 있습니다. (GNU 기능) :

    char *buf = NULL;
    if (asprintf(&buf, "%s%s%s", header, strDevicename, tail) == -1) {
       /* handle memory allocation failure */
    }
    ...
    free(buf);
    
    

    당신이 asprintf  사용할 수없는 경우 malloc 를 사용하여 충분한 메모리를 (위와 같이) 할당 할 수 있습니다  그런 다음 snprintf 를 사용하십시오. .

  • 답변 # 2

    코드에서 배열의 크기 header  는 제공된 이니셜 라이저 문자열의 크기에 따라 결정되며 추가 문자를 저장 (또는추가) 할 수있는 추가 공간이 없습니다.

    인용구 C11 §6.7.9 장

    와이즈 비즈

    다음,

    If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. The array type is completed at the end of its initializer list.

    §7.24.3.1

    장에서 와이즈 비즈 와이즈 비즈  함수는 strcat() 가 가리키는 문자열의 사본을 추가합니다.  (포함하는   

    The 가 가리키는 문자열의 끝까지 널 문자 종료) . [...]

    대상 strcat 를 나타내는

     (여기서 s2 )는 연결된 문자열을 보관하기에 충분한 저장 공간이 있어야합니다.

    따라서 s1   s1 와 함께  할당 된 과거 메모리를 실행할 때 소스로 여기에서 정의되지 않은 동작을 호출합니다.

    header 를 만들어야합니다  이니셜 라이저 문자열로 채운 후 충분한 공간이 남아 있어야합니다. 배열에 고정 된 크기를 사용하십시오. 초기화 문자열로 채운 후에 훨씬 더 많은 양이 있습니다.

    strcat()
    
    

  • 답변 # 3

    header 에서 :

    와이즈 비즈

    당신은 header 를 보장해야합니다  배열은 #define STRSIZ 512 char header[STRSIZ] = "POST /api/add HTT......... 를 작성할 수 있도록 충분히 크게 할당됩니다.  초기 크기 외에도 바이트. 그렇지 않으면 (아마 원격으로 악용 가능한) 버퍼 오버런 취약점이 있습니다.

    아마도 pyzwyz  함수에 로컬로 할당됩니까? 이 경우 man 3 strcat 사용을 고려해야합니다  또는

    The strings may not overlap, and the dest string must have enough space for the result. If dest is not large enough, program behavior is unpredictable;buffer overruns are a favorite avenue for attacking secure programs.

     정적 크기에 의존하기보다는 적절한 크기의 메모리 블록을 얻는 것. 해당 기능의 오류도 처리해야합니다.

    또한, 당신은 항상 안전한 대안 header 를 선호해야합니다  평범한 strlen(strDeviceName) + 5 이상 header 로  추가 할 바이트 수에 대한 추가 인수를 사용하고 오버플로가 발생하더라도 버퍼가 항상 Null로 종료되도록합니다.

  • 답변 # 4

    전체 문자열에 충분한 공간을 할당해야합니다. 맨 페이지 :

    alloca
    
    

    "올바른"방법으로 필요한 것을 정확하게 할당 할 수 있습니다 :

    malloc
    
    

    아니면 게으른 방법으로 전체적으로 정리하십시오 :

    strncat
    
    

  • 답변 # 5

    충분한 공간이 필요하므로 새 공간에서 두 공간을 모두 복제 할 수 있습니다 :

    strcat
    
    

    strncat

  • 이전 클래스 내 Kotlin 확장 기능 테스트
  • 다음 c# - MVC ViewModel이 다시 게시되지 않음