Merge pull request #252 from xexyl/1994-shapiro
Updates to 1994/shapiro including possible bug
This commit is contained in:
5 files changed
+297
-157
No files matched your search
@@ -109,7 +109,7 @@ ENTRY= shapiro
|
|||||||
PROG= ${ENTRY}
|
PROG= ${ENTRY}
|
||||||
#
|
#
|
||||||
OBJ= ${PROG}.o
|
OBJ= ${PROG}.o
|
||||||
DATA= shapiro.info
|
DATA= shapiro.md
|
||||||
TARGET= ${PROG}
|
TARGET= ${PROG}
|
||||||
#
|
#
|
||||||
ALT_OBJ=
|
ALT_OBJ=
|
||||||
|
|||||||
+78
-44
@@ -1,62 +1,96 @@
|
|||||||
# Most Well Rounded Obfuscation:
|
# Most Well Rounded Obfuscation:
|
||||||
|
|
||||||
Andrew T. Shapiro
|
Andrew T. Shapiro
|
||||||
CSES/CIRES University of Colorado
|
CSES/CIRES University of Colorado
|
||||||
Campus Box 216
|
Campus Box 216
|
||||||
Boulder, CO 80309-0216
|
Boulder, CO 80309-0216
|
||||||
USA
|
USA
|
||||||
|
|
||||||
## To build:
|
## To build:
|
||||||
|
|
||||||
make all
|
make all
|
||||||
|
|
||||||
## To run
|
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) pointed out a potential
|
||||||
|
bug on systems where `EOF != -1`. The problem is that `getc()` and the related
|
||||||
|
functions do not return `-1` on EOF or error but rather `EOF` but the program
|
||||||
|
assumes `-1` (conversely when using the `getopt()` functions one should not
|
||||||
|
check for EOF but -1 as the functions return -1 not EOF but the standard does
|
||||||
|
not require `EOF` to be -1, just a negative number. However changing it to check
|
||||||
|
for `!=EOF` caused a problem due to the clever encoding of the code. See
|
||||||
|
[bugs.md](/bugs.md) for more details if you wish to try and fix this (Cody is
|
||||||
|
here and there working on it along with other things and will change this
|
||||||
|
message when it's fixed assuming it's feasible).
|
||||||
|
|
||||||
|
|
||||||
|
## To run:
|
||||||
|
|
||||||
./shapiro &
|
./shapiro &
|
||||||
|
|
||||||
## Judges' comments
|
## Try:
|
||||||
|
|
||||||
This entry has many different levels of obfuscation, and yet the
|
```sh
|
||||||
source file is self documenting. :-)
|
./shapiro
|
||||||
|
^Z
|
||||||
|
bg
|
||||||
|
ps x
|
||||||
|
^C
|
||||||
|
|
||||||
From time to time, run ps and look at the new processes.
|
./shapiro_t1
|
||||||
|
```
|
||||||
|
|
||||||
See shapiro.info for more information in the internals of this program.
|
Notice what you see in the output of `ps`!
|
||||||
The file shapiro.alt contains a non-obfuscated version of this program.
|
|
||||||
|
|
||||||
## Author's comments
|
|
||||||
|
|
||||||
The basic theme (pun) of this program is:
|
## Judges' comments:
|
||||||
|
|
||||||
"This time (everything) is not where it should be."
|
This entry has many different levels of obfuscation, and yet the
|
||||||
~~~~
|
source file is self documenting. :-)
|
||||||
My entry (shapiro.c) is mostly comment, formatted in the shape of a
|
|
||||||
clock. If you strip out the comments and look at the code you will
|
From time to time, run ps and look at the new processes.
|
||||||
quickly realize that the comments were the important part and that
|
|
||||||
the code does very little (see pun above). It writes (to stdout)
|
See [shapiro.md](shapiro.md) for more information in the internals of this program.
|
||||||
another C program (shapiro_t2.c). This is the first level of
|
The file [shapiro.alt.c](shapiro.alt.c) contains a non-obfuscated version of
|
||||||
obfuscation.
|
this program. Note that this alt file is currently missing. See
|
||||||
|
[bugs.md](/bugs.md) for details.
|
||||||
The second program (shapiro_t2.c if you use the build/make file)
|
|
||||||
prints a clock in the upper right hand corner of your VTxxx/ANSI
|
|
||||||
display.
|
## Author's comments:
|
||||||
|
|
||||||
Most of the surface obfuscation in the second program (shapiro_t2.c)
|
The basic theme (pun) of this program is:
|
||||||
was an attempt to make it as small as possible. You should be able to
|
|
||||||
see around this with cb(1) and some more intelligent variable names.
|
|
||||||
Once you get past this you will realize that the third level of
|
> "This time (everything) is not where it should be."
|
||||||
obfuscation is a six member client/server hierarchy.
|
> ~~~~
|
||||||
(See the second info file for a detailed description of the algorithm.)
|
|
||||||
|
|
||||||
Lint complains about: precedence confusion, K may be used before set,
|
My entry ([shapiro.c](shapiro.c)) is mostly comment, formatted in the shape of a
|
||||||
main() returns random value to invocation environment, value type used
|
clock. If you strip out the comments and look at the code you will
|
||||||
inconsistently, value type declared inconsistently, function argument
|
quickly realize that the comments were the important part and that
|
||||||
( number ) used inconsistently, function returns value which is always
|
the code does very little (see pun above). It writes (to stdout)
|
||||||
ignored, function returns value which is sometimes ignored
|
another C program ([shapiro_t2.c](shapiro_t2.c)). This is the first level of
|
||||||
All of which are harmless (famous last words).
|
obfuscation.
|
||||||
|
|
||||||
This may or may not work on non ASCII systems (I could not find one to
|
The second program ([shapiro_t2.c](shapiro_t2.c) if you use the Makefile
|
||||||
test it on.)
|
prints a clock in the upper right hand corner of your VTxxx/ANSI display.
|
||||||
|
|
||||||
|
Most of the surface obfuscation in the second program
|
||||||
|
([shapiro_t2.c](shapiro_t2.c))
|
||||||
|
was an attempt to make it as small as possible. You should be able to
|
||||||
|
see around this with cb(1) and some more intelligent variable names.
|
||||||
|
Once you get past this you will realize that the third level of
|
||||||
|
obfuscation is a six member client/server hierarchy.
|
||||||
|
(See the [shapiro.md](shapiro.md) file for a detailed description of the
|
||||||
|
algorithm.)
|
||||||
|
|
||||||
|
Lint complains about: precedence confusion, `K` may be used before set,
|
||||||
|
main() returns random value to invocation environment, value type used
|
||||||
|
inconsistently, value type declared inconsistently, function argument
|
||||||
|
(number) used inconsistently, function returns value which is always
|
||||||
|
ignored, function returns value which is sometimes ignored.
|
||||||
|
All of which are harmless (famous last words).
|
||||||
|
|
||||||
|
This may or may not work on non ASCII systems (I could not find one to
|
||||||
|
test it on.)
|
||||||
|
|
||||||
## Copyright and CC BY-SA 4.0 License:
|
## Copyright and CC BY-SA 4.0 License:
|
||||||
|
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
HINTS
|
|
||||||
~~~~~
|
|
||||||
For the first program (prog.c):
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
This is a very simple program:
|
|
||||||
|
|
||||||
1. #include <stdio.h>
|
|
||||||
2. main()
|
|
||||||
3. {
|
|
||||||
4. int K,L,M=0;
|
|
||||||
5. FILE *J;
|
|
||||||
6. J=fopen(__FILE__,"r");
|
|
||||||
7. for(;
|
|
||||||
8. (L=getc(J))!=-1;
|
|
||||||
9. L>='J'&&L<='J'+15 &&
|
|
||||||
10. ((M=!M)?K=L:putchar(K-'J'|(L-'J'<<4)))
|
|
||||||
11. );
|
|
||||||
12. exit(0)}
|
|
||||||
|
|
||||||
Lines 1-5 are basic stuff. Line 6 opens the source code for input. Line 7
|
|
||||||
is the loop. Line 8 is read in each character in the file (placed in L)
|
|
||||||
while not EOF(-1). Line 9 is an if expression which filters out all
|
|
||||||
characters not between J and J + 15. Line 10 uses M to execute two different
|
|
||||||
paths the first just stores the character in K. The second path combines
|
|
||||||
the last two characters read in as high and low nibbles of a byte and
|
|
||||||
outputs them. In effect this is a very poor ASCII to binary decoder.
|
|
||||||
The last line is necessary so that make will not stop when it executes
|
|
||||||
this program.
|
|
||||||
|
|
||||||
The second program is encoded into this format and then included (mostly)
|
|
||||||
as a comment.
|
|
||||||
|
|
||||||
Notice that it is impossible to write this program while leaving 16
|
|
||||||
contiguous ASCII characters free for the encoding. Because of this the
|
|
||||||
second program is mostly included as a comment. However, some of the
|
|
||||||
characters of the encoded program are also source code for the decoder.
|
|
||||||
|
|
||||||
For the second program (time.c):
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
1 #include <stdio.h>
|
|
||||||
2 #include <time.h>
|
|
||||||
3 #define o(j,k,m,n,l) {fprintf(j,a[k],m,n,a[l]);fflush(j);}
|
|
||||||
4 char *a[]={"%c+------------+\n","%c+%3d %-8s+\n","seconds","minutes",
|
|
||||||
5 "hours","%s\n","\0337\033[%d;65;H%s\0338"};
|
|
||||||
6 int b[]={0,0,17,14,11,0};
|
|
||||||
7 main(v,c)
|
|
||||||
8 int v;
|
|
||||||
9 char ** c;
|
|
||||||
10 {
|
|
||||||
11 char d[40],*e,f=6;
|
|
||||||
12 time_t g;
|
|
||||||
13 FILE *h,*i;
|
|
||||||
14 while (--f && !pipe(d) && !fork());
|
|
||||||
15 h=fdopen(6-f<<1,"a");
|
|
||||||
16 i=fdopen((6-f<<1)+1,"r");
|
|
||||||
17 for(;;){
|
|
||||||
18 if(f){
|
|
||||||
19 fgets(d,40,i);
|
|
||||||
20 d[strlen(d)-1]='\0';
|
|
||||||
21 if(*d=='0'+f){ sprintf(*c,"%s\n",d+1); o(stdout,6,6-f,d+1,0) }
|
|
||||||
22 if(*d>'0'+f) o(h,5,d,0,0)
|
|
||||||
23 }else{
|
|
||||||
24 time(&g);
|
|
||||||
25 e=asctime(localtime(&g));
|
|
||||||
26 for(v=1;v<6;v++) o(h,v!=1&&v!=6-1,v+'0',atoi(e+b[v]),v)
|
|
||||||
27 sleep(1);
|
|
||||||
28 }}}
|
|
||||||
|
|
||||||
Lines 1 and 2 have to be. Think of 'o' in line 3 as send message with
|
|
||||||
j,k and m as where, format and what. Lines 4 and 5 are all the text
|
|
||||||
strings. Line 6 is the offsets into the time string for the hours,
|
|
||||||
minutes and seconds. Lines 7-13 are basic stuff. Line 14 is the crux of
|
|
||||||
the biscuit. 14 forks off 'f'(6) processes each of which is connected to
|
|
||||||
the ones above and below it with a Unix pipe. It was too difficult to
|
|
||||||
recover the actual fd numbers for the pipe ends in line 14 so I regenerate
|
|
||||||
them and fdopen them (for use with the standard C library functions) on lines
|
|
||||||
15 and 16. Now we have six almost identical processes. Each of which has
|
|
||||||
two files open h and i (up and down). The only difference in each process
|
|
||||||
is the value of f (0 <= f < 6). The five processes where f !=0 are the
|
|
||||||
slave processes and f == 0 is the master. Line 17 says we are going to do
|
|
||||||
this forever. Lines 18 and 23 differentiate between the master and the
|
|
||||||
slaves.
|
|
||||||
|
|
||||||
Lines 19 to 22 are the slave code. Here we read in a line of text from
|
|
||||||
i (down)(line 19) and remove the end of line char (line 20). On line
|
|
||||||
21 if this message is for us (if the first character is our number, f,
|
|
||||||
in ASCII) we do two things:
|
|
||||||
1. We copy the text of the message to *c which is really argv[0].
|
|
||||||
If you are on the correct flavor of Unix this will change the output of
|
|
||||||
the ps(1) command to the string we just put there.
|
|
||||||
2. We send the message (not including the number) to stdout with
|
|
||||||
format number 6 ("\0337\033[%d;65;H%s\0338") If you can read VTxxx
|
|
||||||
(and I read books printed as ANSI/VTxxx codes for fun :-) you know this
|
|
||||||
is the sequence for: remember where we are,
|
|
||||||
go somewhere else,
|
|
||||||
print the message,
|
|
||||||
and return to where we started.
|
|
||||||
Line 22 says if this message is not for us (the number is bigger than ours)
|
|
||||||
send it to h (up).
|
|
||||||
|
|
||||||
Lines 24 to 27 are the master code. Here we get the time and convert it
|
|
||||||
to an ASCII format (lines 24 and 25). Then on line 26 we build and send
|
|
||||||
each of the messages for the slaves. The message uses a different control
|
|
||||||
string for the different slaves. For the first and last slave the message
|
|
||||||
text is just "%c+------------+\n" (slave number, text, newline.) For the
|
|
||||||
other slaves it is "%c+%3d %-8s+\n" (slave number, number, units, newline).
|
|
||||||
The slave number is v+'0'. The number (if used) is atoi(e+b[v]) and the
|
|
||||||
units are just the string in the slave number position.
|
|
||||||
|
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
# HINTS
|
||||||
|
|
||||||
|
For the first program (prog.c):
|
||||||
|
|
||||||
|
|
||||||
|
This is a very simple program:
|
||||||
|
|
||||||
|
```
|
||||||
|
1. #include <stdio.h>
|
||||||
|
2. main()
|
||||||
|
3. {
|
||||||
|
4. int K,L,M=0;
|
||||||
|
5. FILE *J;
|
||||||
|
6. J=fopen(__FILE__,"r");
|
||||||
|
7. for(;
|
||||||
|
8. (L=getc(J))!=EOF;
|
||||||
|
9. L>='J'&&L<='J'+15 &&
|
||||||
|
10. ((M=!M)?K=L:putchar(K-'J'|(L-'J'<<4)))
|
||||||
|
11. );
|
||||||
|
12. exit(0);}
|
||||||
|
```
|
||||||
|
|
||||||
|
Lines 1-5 are basic stuff. Line 6 opens the source code for input. Line 7
|
||||||
|
is the loop. Line 8 is read in each character in the file (placed in `L`)
|
||||||
|
while not `EOF` (usually `-1`). Line 9 is an if expression which filters out all
|
||||||
|
characters not between `J` and `J + 15`. Line 10 uses `M` to execute two different
|
||||||
|
paths the first just stores the character in `K`. The second path combines
|
||||||
|
the last two characters read in as high and low nibbles of a byte and
|
||||||
|
outputs them. In effect this is a very poor ASCII to binary decoder.
|
||||||
|
The last line is necessary so that make will not stop when it executes
|
||||||
|
this program.
|
||||||
|
|
||||||
|
The second program is encoded into this format and then included (mostly)
|
||||||
|
as a comment.
|
||||||
|
|
||||||
|
Notice that it is impossible to write this program while leaving 16
|
||||||
|
contiguous ASCII characters free for the encoding. Because of this the
|
||||||
|
second program is mostly included as a comment. However, some of the
|
||||||
|
characters of the encoded program are also source code for the decoder.
|
||||||
|
|
||||||
|
### For the second program (with time.h):
|
||||||
|
|
||||||
|
```
|
||||||
|
1 #include <stdio.h>
|
||||||
|
2 #include <time.h>
|
||||||
|
3 #define o(j,k,m,n,l) {fprintf(j,a[k],m,n,a[l]);fflush(j);}
|
||||||
|
4 char *a[]={"%c+------------+\n","%c+%3d %-8s+\n","seconds","minutes",
|
||||||
|
5 "hours","%s\n","\0337\033[%d;65;H%s\0338"};
|
||||||
|
6 int b[]={0,0,17,14,11,0};
|
||||||
|
7 main(v,c)
|
||||||
|
8 int v;
|
||||||
|
9 char ** c;
|
||||||
|
10 {
|
||||||
|
11 char d[40],*e,f=6;
|
||||||
|
12 time_t g;
|
||||||
|
13 FILE *h,*i;
|
||||||
|
14 while (--f && !pipe(d) && !fork());
|
||||||
|
15 h=fdopen(6-f<<1,"a");
|
||||||
|
16 i=fdopen((6-f<<1)+1,"r");
|
||||||
|
17 for(;;){
|
||||||
|
18 if(f){
|
||||||
|
19 fgets(d,40,i);
|
||||||
|
20 d[strlen(d)-1]='\0';
|
||||||
|
21 if(*d=='0'+f){ sprintf(*c,"%s\n",d+1); o(stdout,6,6-f,d+1,0) }
|
||||||
|
22 if(*d>'0'+f) o(h,5,d,0,0)
|
||||||
|
23 }else{
|
||||||
|
24 time(&g);
|
||||||
|
25 e=asctime(localtime(&g));
|
||||||
|
26 for(v=1;v<6;v++) o(h,v!=1&&v!=6-1,v+'0',atoi(e+b[v]),v)
|
||||||
|
27 sleep(1);
|
||||||
|
28 }}}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Lines 1 and 2 have to be. Think of `o` in line 3 as send message with
|
||||||
|
`j`,`k` and `m` as where, format and what. Lines 4 and 5 are all the text
|
||||||
|
strings. Line 6 is the offsets into the time string for the hours,
|
||||||
|
minutes and seconds. Lines 7-13 are basic stuff. Line 14 is the crux of
|
||||||
|
the biscuit. 14 forks off `f` (6) processes each of which is connected to
|
||||||
|
the ones above and below it with a Unix pipe. It was too difficult to
|
||||||
|
recover the actual FD numbers for the pipe ends in line 14 so I regenerate
|
||||||
|
them and `fdopen()` them (for use with the standard C library functions) on lines
|
||||||
|
15 and 16. Now we have six almost identical processes. Each of which has
|
||||||
|
two files open `h` and `i` (up and down). The only difference in each process
|
||||||
|
is the value of `f` (`0 <= f < 6`). The five processes where `f !=0` are the
|
||||||
|
slave processes and `f == 0` is the master. Line 17 says we are going to do
|
||||||
|
this forever. Lines 18 and 23 differentiate between the master and the
|
||||||
|
slaves.
|
||||||
|
|
||||||
|
Lines 19 to 22 are the slave code. Here we read in a line of text from
|
||||||
|
`i` (down)(line 19) and remove the end of line char (line 20). On line
|
||||||
|
21 if this message is for us (if the first character is our number, `f`,
|
||||||
|
in ASCII) we do two things:
|
||||||
|
|
||||||
|
1. We copy the text of the message to `*c` which is really argv[0]. If you are
|
||||||
|
on the correct flavor of Unix this will change the output of the `ps(1)` command
|
||||||
|
to the string we just put there.
|
||||||
|
2. We send the message (not including the number) to stdout with format number 6
|
||||||
|
(`"\0337\033[%d;65;H%s\0338"`) If you can read VTxxx (and I read books printed
|
||||||
|
as ANSI/VTxxx codes for fun :-) ) you know this is the sequence for:
|
||||||
|
|
||||||
|
remember where we are,
|
||||||
|
go somewhere else,
|
||||||
|
print the message,
|
||||||
|
and return to where we started.
|
||||||
|
|
||||||
|
Line 22 says if this message is not for us (the number is bigger than ours)
|
||||||
|
send it to `h` (up).
|
||||||
|
|
||||||
|
Lines 24 to 27 are the master code. Here we get the time and convert it
|
||||||
|
to an ASCII format (lines 24 and 25). Then on line 26 we build and send
|
||||||
|
each of the messages for the slaves. The message uses a different control
|
||||||
|
string for the different slaves. For the first and last slave the message
|
||||||
|
text is just `"%c+------------+\n"` (slave number, text, newline.) For the
|
||||||
|
other slaves it is `"%c+%3d %-8s+\n"` (slave number, number, units, newline).
|
||||||
|
The slave number is `v+'0'`. The number (if used) is `atoi(e+b[v])` and the
|
||||||
|
units are just the string in the slave number position.
|
||||||
|
|
||||||
@@ -522,13 +522,13 @@ If you join the lines you end up with:
|
|||||||
|
|
||||||
If you look at column 25 which is the end of the word 'mh111' and you go down to
|
If you look at column 25 which is the end of the word 'mh111' and you go down to
|
||||||
the next row you'll see a 0 and if you go one row down another 0. This is the
|
the next row you'll see a 0 and if you go one row down another 0. This is the
|
||||||
buffer size, 100, for `u`. The column to the left is the same for the `t`
|
buffer size, 100, for `u`! The column to the left is the same for the `t`
|
||||||
variable.
|
variable.
|
||||||
|
|
||||||
Thus it seems that in order to get the generated output correct one needs to
|
Thus it seems that in order to get the generated output correct one needs to
|
||||||
provide the correct input in comments or possibly by rearranging some of the
|
provide the correct input in comments or possibly by rearranging some of the
|
||||||
code (this was required to make the generated code compile at all when changing
|
code (this was actually required to make the generated code compile at all when
|
||||||
the buffer size).
|
changing the buffer size, see below).
|
||||||
|
|
||||||
### Important points:
|
### Important points:
|
||||||
|
|
||||||
@@ -550,6 +550,103 @@ can cause a compilation error! Make sure that the output of:
|
|||||||
can be compiled and the output of that new program when fed itself can also be
|
can be compiled and the output of that new program when fed itself can also be
|
||||||
compiled!
|
compiled!
|
||||||
|
|
||||||
|
## [1994/shapiro](1994/shapiro/shapiro.c) ([README.md](1994/shapiro/README.md))
|
||||||
|
## STATUS: missing file - please provide it
|
||||||
|
|
||||||
|
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) noted that the
|
||||||
|
README.md file refers to an alternative version of the code that is not
|
||||||
|
obfuscated but it is missing from the entry directory and the archive. Do you
|
||||||
|
have this file?
|
||||||
|
|
||||||
|
We would be grateful if you could provide it to us. If you can provide this
|
||||||
|
file you might consider removing this entry from this file as well but if not
|
||||||
|
we'll take care of it.
|
||||||
|
|
||||||
|
### Important reminder to fix the `-1` value check for `getc()`:
|
||||||
|
|
||||||
|
Cody wants to remind you that he fixed the code to not use `-1` for the return
|
||||||
|
value of `getc()`; this is important because `EOF` is **NOT** guaranteed to be
|
||||||
|
`-1` but rather any negative value. On systems where `EOF != -1` the program
|
||||||
|
would enter an infinite loop until the program crashed, by chance reads a `-1`
|
||||||
|
or was killed. See the README.md for more details. If you don't feel comfortable
|
||||||
|
changing it to `EOF` Cody will happily do it for you but otherwise go right
|
||||||
|
ahead. We'll credit you in the README.md file regardless.
|
||||||
|
|
||||||
|
|
||||||
|
## STATUS: doesn't work with some platforms - please help us fix
|
||||||
|
|
||||||
|
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) pointed out a potential
|
||||||
|
bug in [1994/shapiro](1994/shapiro/shapiro.c) on systems where `EOF != -1` as
|
||||||
|
the code assumes that `EOF` will always be `-1`. As the standard says (see `7.21
|
||||||
|
Input/output<stdio.h>` subsection 1) it only has to be a negative int, not
|
||||||
|
necessarily `-1`. The problem is that the source file's last character is a
|
||||||
|
newline (10 in decimal) and so on systems where `EOF != -1` the `getc()`
|
||||||
|
functions would not terminate the loop (but see below). This would cause a
|
||||||
|
breakage in the entry.
|
||||||
|
|
||||||
|
However due to clever encoding of the code it is not a simple matter of applying
|
||||||
|
the following patch:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
diff --git i/1994/shapiro/shapiro.c w/1994/shapiro/shapiro.c
|
||||||
|
index d2da120c7bc4e251b7624859e48f47f188d398e9..e054a1ceb067b82bf37c07e5ce75e82be7a03b85 100644
|
||||||
|
--- i/1994/shapiro/shapiro.c
|
||||||
|
+++ w/1994/shapiro/shapiro.c
|
||||||
|
@@ -9,11 +9,11 @@
|
||||||
|
/*PPPPVPOQMQRPR*/=0;FILE/*TPSLUMWQT*/ *
|
||||||
|
J/*MPRPKPLQ*/; J= fopen(__FILE__
|
||||||
|
/*T*/,"r");for (;( L/*KPUOWOWMUQ
|
||||||
|
LLOLMPULWLWL WLW LWLWLWLWLWLW
|
||||||
|
LWLWLULVOXP LLV LLLOLMPULOL
|
||||||
|
- MMNP*/=getc (J) )!= -1;L/*
|
||||||
|
+ MMNP*/=getc (J) )!=EOF;L/*
|
||||||
|
OLWLRMMQUL VOX PLLVLLLMQO
|
||||||
|
PMPYPXPNP MQL LVLLLWPSP
|
||||||
|
XPOQNQOPMQ LLV LTj*/>='J'
|
||||||
|
&&L/*LRPYP OQL QMQLLVLLL
|
||||||
|
OLMQVOXPL LVL LLVOe*/<=
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
as doing so will cause `warning: illegal character encoding in string
|
||||||
|
literal` and the error `error: source file is not valid UTF-8`. Looking at the
|
||||||
|
file you'll see on line 4 of `shapiro_t2.c`:
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
char *a[]={"%c+------------+\n","%c+%3dPRÒ<82>3·Âå&Â"2W6öæF6'Â"Ò<96>æVGW6'¢ <82>öV'7'Â"R2Çå&Â"Â^E33sÃ^E33³UB¶cS³<83>T2Ç^E33<83>#Ò·£<90>æF^G"¶ÕÕ³^GÃ^BÃ^RsÃ^RCÃ^R^SÃ^BÓ·£Ð^V<96>æ<86>bÇ2<96><92>æF^Gb·3<86>^V&^G¢¢^B2¶£°7<86>^V&^GB¶E^CÓÅ¢RÆbÖc³£@<97>ÖVöE^Gr¶£`<94>ÄT^D¢<82>Æ¢<92>¶£p<87><96>ÆV^F<82>ÒÒb^Fbb^B^R^B<97>^FW<86>B<96>^Bbb^B^Rbö&·<86><92><92>²£<80>ÖcFö^FWæ<86>bÓbÆÃ^SÃ"^R&<92>²<93>ÖcFö^FWæ<86><82>bÓbÆÃ^S<93>²^RÃ""'<92>²£`ö&<87>²³<93>²<97>f<86>b<96>²gvVF7<87>BÆB^CÃ<92><96>²C¶5G'ÇVæ<86>B<96>Ò^RÓÕsÂ^Es²£<90>f<86>¢BÖÓs^Bs²b<96>²7^G'<97>æFg<86>¢2Æ"R2Çå&ÂB¶^R<93>²ó<86>2GGöVGÇbÃbÓbÆB¶^RÃ^B<93>Ò§<90>f<86>¢Bæs^Bs²b<96>ò<86><82>ÆRÃBÆ^BÃ^B<93>ÒWÆ6W¶G<97>ÖV<86>br<96>²SÖ^S67F<97>ÖV<86>Âö6^VÆF<97>ÖV<86>br<96><92>²£`ö&<87>b×^S³cÇc³c·²<92>ò<86><82>Æb^WÒ^Scbb^WÒcÓ^RÃb·r^BsÂ^RF÷<96><86>R¶"¶e×<95>Âb<97>2ÇVV^F<87>^R<93>²Ó××§
|
||||||
|
```
|
||||||
|
|
||||||
|
when it should be something entirely different. For what it should be try
|
||||||
|
running `make clobber all ; cat shapiro_t2.c` or else look at the second program
|
||||||
|
in the spoilers file [shapiro.md](1994/shapiro/shapiro.md]).
|
||||||
|
|
||||||
|
Cody is working will be working on this here and there but if you have a fix or
|
||||||
|
any suggestions you're welcome to provide it or them.
|
||||||
|
|
||||||
|
Cody points you to the README.md file for what should happen when the entry is
|
||||||
|
successfully compiled (including no compilation errors when running `make
|
||||||
|
clobber all`).
|
||||||
|
|
||||||
|
Another problem is that in the [shapiro.md](shapiro.md) file the first program
|
||||||
|
does not work.
|
||||||
|
|
||||||
|
### Tips on this entry:
|
||||||
|
|
||||||
|
Cody provides some tips on this entry:
|
||||||
|
|
||||||
|
First: the comments are the important part of this entry. Remove them and the
|
||||||
|
program breaks.
|
||||||
|
|
||||||
|
Second and perhaps part of the problem with changing the code to `EOF` instead
|
||||||
|
of `-1` is the `for` loop particularly to do with the bitwise operations,
|
||||||
|
perhaps also made worse by the seemingly gibberish comments.
|
||||||
|
|
||||||
|
Another important point is that the Makefile compiles the program as
|
||||||
|
`shapiro_t1` so that the source code that corresponds with it is actually
|
||||||
|
[shapiro.c](1994/shapiro/shapiro.c). But notice how running `shapiro_t1` results
|
||||||
|
in different functionality than `shapiro` itself? The source code that
|
||||||
|
`shapiro_t1` generates, `shapiro_t2.c`, is what is compiled into `shapiro`.
|
||||||
|
|
||||||
# 1995
|
# 1995
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user