Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Jonathan Wilkes
purr-data
Commits
b9f4529f
Commit
b9f4529f
authored
Oct 09, 2018
by
Jonathan Wilkes
Browse files
fix overflow with large precision specifiers
parent
cbf0ab07
Pipeline
#1403
passed with stage
in 410 minutes and 24 seconds
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
pd/src/x_connective.c
View file @
b9f4529f
...
...
@@ -1449,21 +1449,25 @@ static void until_setup(void)
static
t_class
*
makefilename_class
;
typedef
enum
{
NONE
=
0
,
INT
,
FLOAT
,
STRING
,
POINTER
,
}
t_printtype
;
typedef
struct
_makefilename
{
t_object
x_obj
;
t_symbol
*
x_format
;
t_atomtype
x_accept
;
int
x_intconvert
;
t_printtype
x_accept
;
}
t_makefilename
;
static
void
makefilename_scanformat
(
t_makefilename
*
x
)
static
const
char
*
makefilename_
do
scanformat
(
const
char
*
str
,
t_printtype
*
typ
)
{
int
infmt
=
0
;
char
*
str
;
if
(
!
x
->
x_format
)
return
;
x
->
x_accept
=
A_NULL
;
for
(
str
=
x
->
x_format
->
s_name
;
*
str
;
str
++
)
for
(;
*
str
;
str
++
)
{
if
(
!
infmt
&&
*
str
==
'%'
)
{
...
...
@@ -1472,27 +1476,58 @@ static void makefilename_scanformat(t_makefilename *x)
}
if
(
infmt
)
{
if
(
*
str
==
'%'
)
{
infmt
=
0
;
continue
;
}
if
(
strchr
(
"-.#0123456789"
,
*
str
)
!=
0
)
continue
;
if
(
*
str
==
's'
)
{
x
->
x_accept
=
A_SYMBOL
;
x
->
x_intconvert
=
0
;
break
;
*
typ
=
STRING
;
return
str
;
}
if
(
strchr
(
"fgGeE"
,
*
str
)
!=
0
)
{
x
->
x_accept
=
A_FLOAT
;
x
->
x_intconvert
=
0
;
break
;
*
typ
=
FLOAT
;
return
str
;
}
if
(
strchr
(
"xXdiouc"
,
*
str
)
!=
0
)
{
x
->
x_accept
=
A_FLOAT
;
x
->
x_intconvert
=
1
;
break
;
*
typ
=
INT
;
return
str
;
}
if
(
strchr
(
"p"
,
*
str
)
!=
0
)
{
*
typ
=
POINTER
;
return
str
;
}
infmt
=
0
;
}
}
*
typ
=
NONE
;
return
str
;
}
static
void
makefilename_scanformat
(
t_makefilename
*
x
)
{
const
char
*
str
;
t_printtype
typ
;
if
(
!
x
->
x_format
)
return
;
str
=
x
->
x_format
->
s_name
;
str
=
makefilename_doscanformat
(
str
,
&
typ
);
x
->
x_accept
=
typ
;
if
(
str
&&
(
NONE
!=
typ
))
{
/* try again, to see if there's another format specifier
(which we forbid) */
str
=
makefilename_doscanformat
(
str
,
&
typ
);
if
(
NONE
!=
typ
)
{
pd_error
(
x
,
"makefilename: invalid format string '%s' "
"(too many format specifiers)"
,
x
->
x_format
->
s_name
);
x
->
x_format
=
0
;
return
;
}
}
}
...
...
@@ -1504,40 +1539,113 @@ static void *makefilename_new(t_symbol *s)
s
=
gensym
(
"file.%d"
);
outlet_new
(
&
x
->
x_obj
,
&
s_symbol
);
x
->
x_format
=
s
;
x
->
x_accept
=
A_NULL
;
x
->
x_intconvert
=
0
;
x
->
x_accept
=
NONE
;
makefilename_scanformat
(
x
);
return
(
x
);
}
static
void
makefilename_snprintf
(
t_makefilename
*
x
,
char
*
buf
,
char
*
fmt
,
...)
{
int
length_minus_null_terminator
;
va_list
ap
;
va_start
(
ap
,
fmt
);
length_minus_null_terminator
=
vsnprintf
(
buf
,
MAXPDSTRING
,
fmt
,
ap
);
va_end
(
ap
);
if
(
length_minus_null_terminator
>=
MAXPDSTRING
)
{
/* Just don't trust snprintf... */
buf
[
MAXPDSTRING
-
1
]
=
'\0'
;
pd_error
(
x
,
"makefilename: output truncated to %d characters"
,
MAXPDSTRING
);
}
}
static
void
makefilename_float
(
t_makefilename
*
x
,
t_floatarg
f
)
{
char
buf
[
MAXPDSTRING
];
if
(
x
->
x_
accept
==
A_FLOAT
)
if
(
!
x
->
x_
format
)
{
if
(
x
->
x_intconvert
)
sprintf
(
buf
,
x
->
x_format
->
s_name
,
(
int
)
f
);
else
sprintf
(
buf
,
x
->
x_format
->
s_name
,
f
);
pd_error
(
x
,
"makefilename: no format specifier given"
);
return
;
}
else
switch
(
x
->
x_accept
)
{
case
NONE
:
makefilename_snprintf
(
x
,
buf
,
"%s"
,
x
->
x_format
->
s_name
);
break
;
case
INT
:
case
POINTER
:
makefilename_snprintf
(
x
,
buf
,
x
->
x_format
->
s_name
,
(
int
)
f
);
break
;
case
FLOAT
:
makefilename_snprintf
(
x
,
buf
,
x
->
x_format
->
s_name
,
f
);
break
;
case
STRING
:
{
char
buf2
[
MAXPDSTRING
];
sprintf
(
buf2
,
"%g"
,
f
);
sprintf
(
buf
,
x
->
x_format
->
s_name
,
buf2
);
makefilename_snprintf
(
x
,
buf2
,
"%g"
,
f
);
makefilename_snprintf
(
x
,
buf
,
x
->
x_format
->
s_name
,
buf2
);
break
;
}
default:
makefilename_snprintf
(
x
,
buf
,
"%s"
,
x
->
x_format
->
s_name
);
}
if
(
buf
[
0
]
!=
0
)
outlet_symbol
(
x
->
x_obj
.
ob_outlet
,
gensym
(
buf
));
outlet_symbol
(
x
->
x_obj
.
ob_outlet
,
gensym
(
buf
));
}
static
void
makefilename_symbol
(
t_makefilename
*
x
,
t_symbol
*
s
)
{
char
buf
[
MAXPDSTRING
];
if
(
x
->
x_accept
==
A_SYMBOL
)
sprintf
(
buf
,
x
->
x_format
->
s_name
,
s
->
s_name
);
else
sprintf
(
buf
,
x
->
x_format
->
s_name
,
0
);
if
(
!
x
->
x_format
)
{
pd_error
(
x
,
"makefilename: no format specifier given"
);
return
;
}
switch
(
x
->
x_accept
)
{
case
STRING
:
case
POINTER
:
makefilename_snprintf
(
x
,
buf
,
x
->
x_format
->
s_name
,
s
->
s_name
);
break
;
case
INT
:
makefilename_snprintf
(
x
,
buf
,
x
->
x_format
->
s_name
,
0
);
break
;
case
FLOAT
:
makefilename_snprintf
(
x
,
buf
,
x
->
x_format
->
s_name
,
0
.);
break
;
case
NONE
:
makefilename_snprintf
(
x
,
buf
,
"%s"
,
x
->
x_format
->
s_name
);
break
;
default:
makefilename_snprintf
(
x
,
buf
,
"%s"
,
x
->
x_format
->
s_name
);
}
if
(
buf
[
0
]
!=
0
)
outlet_symbol
(
x
->
x_obj
.
ob_outlet
,
gensym
(
buf
));
}
static
void
makefilename_bang
(
t_makefilename
*
x
)
{
char
buf
[
MAXPDSTRING
];
if
(
!
x
->
x_format
)
{
pd_error
(
x
,
"makefilename: no format specifier given"
);
return
;
}
switch
(
x
->
x_accept
)
{
case
INT
:
makefilename_snprintf
(
x
,
buf
,
x
->
x_format
->
s_name
,
0
);
break
;
case
FLOAT
:
makefilename_snprintf
(
x
,
buf
,
x
->
x_format
->
s_name
,
0
.);
break
;
case
NONE
:
makefilename_snprintf
(
x
,
buf
,
"%s"
,
x
->
x_format
->
s_name
);
break
;
default:
makefilename_snprintf
(
x
,
buf
,
"%s"
,
x
->
x_format
->
s_name
);
}
if
(
buf
[
0
]
!=
0
)
outlet_symbol
(
x
->
x_obj
.
ob_outlet
,
gensym
(
buf
));
outlet_symbol
(
x
->
x_obj
.
ob_outlet
,
gensym
(
buf
));
}
static
void
makefilename_set
(
t_makefilename
*
x
,
t_symbol
*
s
)
...
...
@@ -1553,6 +1661,7 @@ static void makefilename_setup(void)
sizeof
(
t_makefilename
),
0
,
A_DEFSYM
,
0
);
class_addfloat
(
makefilename_class
,
makefilename_float
);
class_addsymbol
(
makefilename_class
,
makefilename_symbol
);
class_addbang
(
makefilename_class
,
makefilename_bang
);
class_addmethod
(
makefilename_class
,
(
t_method
)
makefilename_set
,
gensym
(
"set"
),
A_SYMBOL
,
0
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment