2021년 1월 5일 화요일

[소프트웨어 저작권침해] 소프트웨어 프로그램의 저작권의 침해 판단 – 문언적 침해와 비문언적 침해


Zenimax vs. Oculus 간의 미국 소송에서 소프트웨어 프로그램에 대한 저작권 침해가 인정되었습니다. 여기서 저작권은 아이디어가 아닌 표현을 보호하므로 소프트웨어의 경우에는 소스코드를 보호하지만 해당 소스코드의 기능을 보호하지는 않고, 기능은 영업비밀 또는 특허로 보호할 있습니다. 그리고 저작권 침해는 저작권자의 동의 없이 저작물(, 소프트웨어의 경우 소스코드) 사용하는 경우에 발생합니다. 그런데 Zenimax vs. Oculus 소송에서는 문언적 복제(literal copying) 아닌 비문언적 복제(non-literal copying) 여부가 쟁점이 되었습니다.

 

저작권의 보호를 받는 표현이란 소스 코드와 같은 문언 요소(literal elements) 프로그램 아키텍처, 구조, 시퀀스 구성, 동작 모듈, 컴퓨터 사용자 인터페이스와 같은 비문언 요소(non-literal elements) 포함됩니다. 그래서 소프트웨어 저작권 침해는 단순히 코드를 똑같이 복제하는 문언적 침해(literal infringement) 경우에만 문제가 되는 것이 아니라 비문언적 침해(non-literal infringement) 중요한 침해 행위가 있습니다.

 

Zenimax vs. Oculus 소송의 결과에 따르면, 경쟁 업체에서 소프트웨어 엔지니어를 뽑을 경우에 해당 엔지니어가 자사에서 개발한 프로젝트에서 경쟁 업체의 소프트웨어 저작권을 침해할 소지가 없는지 충분히 검토하고 해당 엔지니어에게도 주지시켜야 것입니다. 아래에서 두가지 소프트웨어 저작권 침해에 대하여 살펴보겠습니다.

 

문언적 복제는 창작성이 있는 타인의 소스코드의 상당한 분량을 그대로 복제할 경우에 발생합니다. 저작권 성립을 위한 창작성은 예술작품과 같은 높은 수준을 요구하고 있지 않으므로, 통상 대부분의 소스코드는 창작성이 인정되고 있습니다. 그리고 동일하게 그대로 복제하지 않고 아래 사례와 같이 주석을 변경하고 삭제하거나 변수 함수의 이름을 변경하는 정도의 피상적인 변경을 가하더라도 문언적 복제가 인정될 있습니다.

// 스택 구현

// C 언어

// STACK 구조체 이용

#include <stdio.h>

#define STACKSIZE 100

 

typedef struct {

int size;

int items[STACKSIZE];

} STACK;

 

int push (STACK *ps, int x)

{

if (ps->size == STACKSIZE) {

printf("Error: stack overflow\n");

return -1;

} else

ps->items[ps->size++] = x;

}

 

int pop (STACK *ps)

{

if (ps->size == 0){

printf("Error: stack underflow\n");

return -1;

} else

return ps->items[–ps->size];

}

 

int main ()

{

STACK *ps;

ps = (STACK*)malloc (sizeof(STACK));

ps->size = 0;

 

printf ("size of stack = %d\n", sizeof(STACK));

 

push (ps, 10);

 

push (ps, 20);

push (ps, 30);

push (ps, 40);

 

printf ("%d\n", pop (ps));

printf ("%d\n", pop (ps));

printf ("%d\n", pop (ps));

printf ("%d\n", pop (ps));

 

free (ps);

 

printf("Press Any Key…");

getchar();

}

// 스택 구현

// C 언어

// STK 구조체 이용

#include <stdio.h>

#define STKSIZE 100

 

typedef struct {

int size;

int items[STKSIZE];

} STK;

 

int stkpush (STK *ps, int x)

{

if (ps->size == STKSIZE) {

printf("Error: stack overflow\n");

return -1;

} else

ps->items[ps->size++] = x;

}

 

int stkpop (STK *ps)

{

if (ps->size == 0){

printf("Error: stack underflow\n");

return -1;

} else

return ps->items[–ps->size];

}

 

int main ()

{

STK *ps;

ps = (STK*)malloc (sizeof(STK));

ps->size = 0;

 

printf ("size of stack = %d\n", sizeof(STK));

 

stkpush (ps, 10);

 

stkpush (ps, 20);

stkpush (ps, 30);

stkpush (ps, 40);

 

printf ("%d\n", stkpop (ps));

printf ("%d\n", stkpop (ps));

printf ("%d\n", stkpop (ps));

printf ("%d\n", stkpop (ps));

 

free (ps);

 

printf("Press Any Key…");

getchar();

}

 

그런데 타인의 소스코드를 확보하였다고 하더라도 많은 경우에 저작권 침해를 피하기 위하여 소스코드를 그대로 복제하여 사용하기보다는 함수 변수 이름을 변경하고 함수 내부의 명령의 순서도 변경하여, 타인의 코드를 복제한 것이 아니라 독자적으로 개발하였다고 있을 정도로 작업을 하게 됩니다. 다만, 위와 같이 의도적인 변경을 하더라도 타인의 코드에 있던 주석 등을 처리하지 못하여 현재 코드에는 없고 타인의 코드에 있던 변수, 함수 등의 설명이 남아 있는 경우가 발생할 있고 이는 타인의 코드를 보고 복제하였다는 강력한 증거가 있습니다. 그리고 때에는 문언적 복제가 발생하였다고 인정될 있습니다. 아래 사례에서는 구조체와 함수의 이름을 변경하고 for loop, print 구문 등을 이용하여 코드를 일부 수정하였습니다만, 3번째 줄에 구조체와 함수의 변경전 명칭을 그대로 두어 복제의 증거가 있습니다.

// 스택 구현

// C 언어

// STACK 구조체, push pop 함수 이용

#include <stdio.h>

#define STACKSIZE 100

 

typedef struct {

int size;

int items[STACKSIZE];

} STACK;

 

int push (STACK *ps, int x)

{

if (ps->size == STACKSIZE) {

printf("Error: stack overflow\n");

return -1;

} else

ps->items[ps->size++] = x;

}

 

int pop (STACK *ps)

{

if (ps->size == 0){

printf("Error: stack underflow\n");

return -1;

} else

return ps->items[–ps->size];

}

 

int main ()

{

STACK *ps;

ps = (STACK*)malloc (sizeof(STACK));

ps->size = 0;

 

printf ("size of stack = %d\n", sizeof(STACK));

 

push (ps, 10);

 

push (ps, 20);

push (ps, 30);

push (ps, 40);

 

printf ("%d\n", pop (ps));

printf ("%d\n", pop (ps));

printf ("%d\n", pop (ps));

printf ("%d\n", pop (ps));

 

free (ps);

 

printf("Press Any Key…");

getchar();

}

// 스택 구현

// C 언어

// STACK 구조체, push pop 함수 이용

#include <stdio.h>

#define STKSIZE 100

#define ERR -1

 

typedef struct {

int size;

int items[STKSIZE];

} STK;

 

int stkpush (STK *ps, int x)

{

if (ps->size == STKSIZE) {

printf("Error: stack overflow\n");

return ERR;

} else

ps->items[ps->size++] = x;

}

 

int stkpop (STK *ps)

{

if (ps->size == 0){

printf("Error: stack underflow\n");

return eRR;

} else

return ps->items[–ps->size];

}

 

int main ()

{

STK *ps;

ps = (STK*)malloc (sizeof(STK));

ps->size = 0;

 

printf ("size of stack = %d\n", sizeof(STK));

 

for (int i=1 ; i<= 4; i++) stkpush(ps, 10*i);

 

for (int i=1; i<=4; i++) printf(“%d\n”, stkpop(ps));

 

free (ps);

 

printf("Press Any Key, this program end…");

getchar();

}

 

위와 같은 문언적 복제를 피하기 위하여 소스코드를 새로 코딩하는 경우에도 타인의 소프트웨어가 가지고 있던 코드의 구조(structure), 시퀀스(sequence), 조직(organization) SSO 그대로 사용하게 되곤 합니다. 이러한 SSO 복제는 비문언적 복제로 저작권 침해에 해당합니다. 다만, SSO 실제 소스코드에 대한 것으로 한정되고, 기능상에 대한 부분까지 확대되지는 않습니다. 아래 그림은 Video Stack 추가하였더라도 유사한 SSO 가진 것으로 비문언적 복제로 판단받을 있습니다

 

위와 같이 소프트웨어 업체가 경쟁업체 또는 동종업체에서 소프트웨어 엔지니어를 영입하는 경우나 타사 제품에 대한 경쟁제품을 개발하기 위하여 타사 제품의 리버스엔지니어링을 통하여 분석하는 경우에, 위와 같이 문언적 복제 이외에도 비문언적 복제 행위로 판단될 여지는 피해야 것입니다.

 

정회목 변호사

 


댓글 없음:

댓글 쓰기